在 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编程开发之textwrap文本样式处理技巧
Nov 13 Python
Python内建数据结构详解
Feb 03 Python
对pandas的算术运算和数据对齐实例详解
Dec 22 Python
50行Python代码获取高考志愿信息的实现方法
Jul 23 Python
python函数不定长参数使用方法解析
Dec 14 Python
python 计算方位角实例(根据两点的坐标计算)
Jan 17 Python
Python获取对象属性的几种方式小结
Mar 12 Python
使用Django清空数据库并重新生成
Apr 03 Python
pycharm 实现调试窗口恢复
Feb 05 Python
Python djanjo之csrf防跨站攻击实验过程
May 14 Python
python全面解析接口返回数据
Feb 12 Python
python如何将mat文件转为png
Jul 15 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排序算法的复习和总结
2012/02/15 PHP
PDO::getAvailableDrivers讲解
2019/01/28 PHP
详解no input file specified 三种解决方法
2019/11/29 PHP
Jquery 跨域访问 Lightswitch OData Service的方法
2013/09/11 Javascript
js 判断所选时间(或者当前时间)是否在某一时间段的实现代码
2015/09/05 Javascript
理解javascript中DOM事件
2015/12/25 Javascript
详解jQuery中ajax.load()方法
2017/01/25 Javascript
JS实现动态添加DOM节点和事件的方法示例
2017/04/28 Javascript
slideToggle+slideup实现手机端折叠菜单效果
2017/05/25 Javascript
nodejs操作mysql实现增删改查的实例
2017/05/28 NodeJs
JavaScript实现简单的树形菜单效果
2017/06/23 Javascript
谈谈VUE种methods watch和compute的区别和联系
2017/08/01 Javascript
关于预加载InstantClick的问题解决方法
2017/09/12 Javascript
windows下更新npm和node的方法
2017/11/30 Javascript
javascript对HTML字符转义与反转义
2018/12/13 Javascript
命令行批量截图Node脚本示例代码
2019/01/25 Javascript
vue实现弹幕功能
2019/10/25 Javascript
[01:10]DOTA2英雄背景故事第四期之混沌法则混沌骑士
2020/07/16 DOTA
在python中安装basemap的教程
2018/09/20 Python
Python Selenium操作Cookie的实例方法
2021/02/28 Python
快速一键生成Python爬虫请求头
2021/03/04 Python
CSS3 :not()选择器实现最后一行li去除某种css样式
2016/10/19 HTML / CSS
Html5获取高德地图定位天气的方法
2019/12/26 HTML / CSS
HTML5 body设置自适应全屏
2020/05/07 HTML / CSS
Avène雅漾美国官方网站:敏感肌肤护理专家
2016/10/24 全球购物
美国南部最大的家族百货公司:Belk
2017/01/30 全球购物
爱尔兰橄榄球店:Irish Rugby Store
2019/12/05 全球购物
俄罗斯香水和化妆品网上商店:NOTINO.ru
2019/12/17 全球购物
师范毕业生自荐信
2013/10/17 职场文书
岗位职责的定义
2013/11/10 职场文书
生日宴会答谢词
2014/01/09 职场文书
岗位职责的构建方法
2014/02/01 职场文书
护士长竞聘书
2014/03/31 职场文书
社区志愿者活动方案
2014/08/18 职场文书
怎样做好公众演讲能力?
2019/08/28 职场文书
Python何绘制带有背景色块的折线图
2022/04/23 Python