在 Python 中利用 Pool 进行多线程


Posted in Python onApril 24, 2022

为什么要引入线程池

如果在程序中经常要用到线程,频繁的创建和销毁线程会浪费很多硬件资源,
所以需要把线程和任务分离。线程可以反复利用,省去了重复创建的麻烦。
在 Process 类中,我们必须显式地创建流程。但是,Pool 类更方便,您不必手动管理它。创建池对象的语法是 ​​multiprocessing.Pool(processes, initializer, initargs, maxtasksperchild, context)​​ 。所有参数都是可选的。

  • processes 表示您要创建的工作进程的数量。默认值通过 os.cpu_count() 获取。
  • initializer第二个初始化器参数是一个用于初始化的函数。
  • initargs 是传递给它的参数。
  • maxtasksperchild 表示分配给每个子进程的任务数。在完成该数量的任务之后,该进程将被一个新的工作进程替换。指定它的好处是任何未使用的资源都将被释放。如果未提供任何内容,则只要池存在,进程就会存在。
import time
from multiprocessing import Pool


def square(x):
print(f"start process:{x}")
square = x * x
print(f"square {x}:{square}")
time.sleep(1)
print(f"end process:{x}")


if __name__ == "__main__":
starttime = time.time()
pool = Pool()
pool.map(square, range(0, 5))
pool.close()
endtime = time.time()
print(f"Time taken {endtime-starttime} seconds")

结果为:

start process:0
start process:1
square 1:1
square 0:0
end process:1
start process:2
end process:0
start process:3
square 2:4
square 3:9
end process:3
end process:2
start process:4
square 4:16
end process:4
Time taken 3.0474610328674316 seconds

在这里,我们从多处理模块中导入 Pool 类。在主函数中,我们创建了一个 Pool 类的对象。 pool.map() 将我们想要并行化的函数和一个可迭代的函数作为参数。它在可迭代的每个项目上运行给定的函数。它还接受一个可选的 chunksize 参数,它将可迭代对象拆分为等于给定大小的块,并将每个块作为单独的任务传递。 pool.close() 用于拒绝新任务。
我们可以看到花费的时间大约是 3 秒。
​pool.imap()​​ 与 ​​pool.map()​​ 方法几乎相同。不同的是,每个项目的结果都是在准备好后立即收到的,而不是等待所有项目都完成。此外, ​​map()​​ 方法将可迭代对象转换为列表(如果不是)。但是, ​​imap()​​ 方法没有。

来看下一个例子:

import time
from multiprocessing import Pool


def square(x):
print(f"start process {x}")
square = x * x
time.sleep(1)
print(f"end process {x}")
return square


if __name__ == "__main__":
pool = Pool()
a = pool.map(square, range(0, 5))
print(a)

运行结果:

start process 0
start process 1
end process 0
start process 2
end process 1
start process 3
end process 2
start process 4
end process 3
end process 4
[0, 1, 4, 9, 16]

from concurrent.futures import ThreadPoolExecutor

def say_hello():
print("Hello")

executor = ThreadPoolExecutor(50)
for i in range(0, 10):
executor.submit(say_hello)

练习

利用 Python 多线程模拟商品秒杀过程,不可以出现超买和超卖的情况。假设A商品有50件参与秒杀活动,10分钟秒杀自动结束。

  • kill_total 商品总数
  • kill_num 成功抢购数
  • kill_flag 有效标志位
  • kill_user 成功抢购的用户ID
from redis_db import pool
import redis
import random
from concurrent.futures import ThreadPoolExecutor

s = set()
while True:
if len(s) == 1000:
break
num = random.randint(10000, 100000)
s.add(num)
print(s)

con = redis.Redis(
connection_pool=pool
)

try:
con.delete("kill_total", "kill_num", "kill_flag", "kill_user")
con.set("kill_total", 50)
con.set("kill_num", 0)
con.set("kill_flag", 1)
con.expire("kill_flag", 600)

except Exception as e:
print(e)
finally:
del con

executor = ThreadPoolExecutor(200)
def buy():
connection = redis.Redis(
connection_pool=pool
)
pipline = connection.pipline()
try:
if connection.exists("kill_flag") == 1:
pipline.watch("kill_num", "kill_user")
total = pipline.get("kill_total")
num = int(pipline.get("kill_num").decode("utf-8"))
if num < total:
pipline.multi()
pipline.incr("kill_num")
user_id = s.pop()
pipline.rpush("kill_user", user_id)

pipline.execute()
except Exception as e:
print(e)
finally:
if "pipline" in dir():
pipline.reset()
del connection

for i in range(0, 1000):
executor.submit(buy)
print("秒杀活动已经结束")

到此这篇关于在 Python 中利用Pool 进行多处理的文章就介绍到这了!


Tags in this post...

Python 相关文章推荐
Python列表append和+的区别浅析
Feb 02 Python
使用Python的Django框架实现事务交易管理的教程
Apr 20 Python
简介Python的collections模块中defaultdict类型的用法
Jul 07 Python
Python循环语句中else的用法总结
Sep 11 Python
Python字典的概念及常见应用实例详解
Oct 30 Python
Tensorflow 定义变量,函数,数值计算等名字的更新方式
Feb 10 Python
解决Python import docx出错DLL load failed的问题
Feb 13 Python
使用OpenCV获取图片连通域数量,并用不同颜色标记函
Jun 04 Python
python中adb有什么功能
Jun 07 Python
python实现sm2和sm4国密(国家商用密码)算法的示例
Sep 26 Python
python中函数返回多个结果的实例方法
Dec 16 Python
如何用python反转图片,视频
Apr 24 Python
Python何绘制带有背景色块的折线图
python中Pyqt5使用Qlabel标签播放视频
Apr 22 #Python
Python使用MapReduce进行简单的销售统计
python使用pycharm安装pyqt5以及相关配置
Python使用DFA算法过滤内容敏感词
python游戏开发之pygame实现接球小游戏
Apr 22 #Python
python游戏开发Pygame框架
Apr 22 #Python
You might like
PHP函数常用用法小结
2010/02/08 PHP
Zend Studio (eclipse)使用速度优化方法
2011/03/23 PHP
显示、隐藏密码
2006/07/01 Javascript
获取网站跟路径的javascript代码(站点及虚拟目录)
2009/10/20 Javascript
JQuery中属性过滤选择器用法实例分析
2015/05/18 Javascript
js基础知识(公有方法、私有方法、特权方法)
2015/11/06 Javascript
jQuery禁用键盘后退屏蔽F5刷新及禁用右键单击
2016/01/22 Javascript
JS获取复选框的值,并传递到后台的实现方法
2016/05/30 Javascript
JSONP原理及应用实例详解
2018/09/13 Javascript
使用webpack搭建vue项目实现脚手架功能
2019/03/15 Javascript
jQuery实现的图片点击放大缩小功能案例
2020/01/02 jQuery
在Chrome DevTools中调试JavaScript的实现
2020/04/07 Javascript
[57:59]EG vs Secret 2018国际邀请赛淘汰赛BO3 第一场 8.22
2018/08/23 DOTA
python处理PHP数组文本文件实例
2014/09/18 Python
深入解析Python的Tornado框架中内置的模板引擎
2016/07/11 Python
django表单实现下拉框的示例讲解
2018/05/29 Python
django中SMTP发送邮件配置详解
2019/07/19 Python
Python学习笔记之函数的定义和作用域实例详解
2019/08/13 Python
详解PyTorch中Tensor的高阶操作
2019/08/18 Python
简单分析python的类变量、实例变量
2019/08/23 Python
关于python中plt.hist参数的使用详解
2019/11/28 Python
python中property和setter装饰器用法
2019/12/19 Python
解决jupyter notebook打不开无反应 浏览器未启动的问题
2020/04/10 Python
python3 简单实现组合设计模式
2020/07/02 Python
python爬取”顶点小说网“《纯阳剑尊》的示例代码
2020/10/16 Python
Rockport乐步美国官网:风靡美国的白宫鞋
2016/11/24 全球购物
Linux文件系统类型
2012/02/15 面试题
计算机专业推荐信范文
2013/11/20 职场文书
暑期社会实践先进个人主要事迹
2014/05/22 职场文书
教师查摆问题自查报告
2014/10/11 职场文书
临床医学生职业规划书范文
2014/10/25 职场文书
交流会主持词
2015/07/02 职场文书
《最后一头战象》教学反思
2016/02/16 职场文书
李白经典诗之一:全文无一“月”字,却句句有月
2019/07/12 职场文书
德劲DE1108畅想
2021/04/22 无线电
Netflix《海贼王》真人版剧集多张片场照曝光
2022/04/04 日漫