在 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字符串连接方式汇总
Aug 21 Python
归纳整理Python中的控制流语句的知识点
Apr 14 Python
Python中协程用法代码详解
Feb 10 Python
利用python实现微信头像加红色数字功能
Mar 26 Python
Ubuntu下使用Python实现游戏制作中的切分图片功能
Mar 30 Python
解决Django数据库makemigrations有变化但是migrate时未变动问题
May 30 Python
详解Numpy中的广播原则/机制
Sep 20 Python
python实现动态数组的示例代码
Jul 15 Python
python+Selenium自动化测试——输入,点击操作
Mar 06 Python
一文弄懂Pytorch的DataLoader, DataSet, Sampler之间的关系
Jul 03 Python
属性与 @property 方法让你的python更高效
Sep 21 Python
Python Socket编程详解
Apr 25 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/03/27 PHP
php版微信小店调用api示例代码
2016/11/12 PHP
PHP快速导出百万级数据到CSV或者EXCEL文件
2020/11/27 PHP
javascript读取RSS数据
2007/01/20 Javascript
Prototype RegExp对象 学习
2009/07/19 Javascript
Tips 带三角可关闭的文字提示
2010/10/06 Javascript
jquery动态添加元素事件失效问题解决方法
2014/05/23 Javascript
javaScript中push函数用法实例分析
2015/06/08 Javascript
jQuery焦点图轮播效果实现方法
2016/12/19 Javascript
nodejs个人博客开发第二步 入口文件
2017/04/12 NodeJs
JS 组件系列之 bootstrap treegrid 组件封装过程
2017/04/28 Javascript
jQuery Validate表单验证插件实现代码
2017/06/08 jQuery
JS实现图片切换效果
2018/11/17 Javascript
react写一个select组件的实现代码
2019/04/03 Javascript
Vue列表循环从指定下标开始的多种解决方案
2020/04/08 Javascript
js和jquery判断数据类型的4种方法总结
2020/08/28 jQuery
python函数式编程学习之yield表达式形式详解
2018/03/25 Python
Python简单实现阿拉伯数字和罗马数字的互相转换功能示例
2018/04/17 Python
Pandas:DataFrame对象的基础操作方法
2018/06/07 Python
浅谈Python接口对json串的处理方法
2018/12/19 Python
详解Python正则表达式re模块
2019/03/19 Python
使用OpCode绕过Python沙箱的方法详解
2019/09/03 Python
python自动点赞功能的实现思路
2020/02/26 Python
CSS3实现水平居中、垂直居中、水平垂直居中的实例代码
2020/02/27 HTML / CSS
html5理解head_动力节点Java学院整理
2017/07/13 HTML / CSS
详解Canvas实用库Fabric.js使用手册
2019/01/07 HTML / CSS
Html5饼图绘制实现统计图的方法
2020/08/05 HTML / CSS
美国著名的团购网站:Woot
2016/08/02 全球购物
德国前卫设计师时装在线商店:Luxury Loft
2019/11/04 全球购物
J2ee常用的设计模式?说明工厂模式
2015/05/21 面试题
党员年终民主评议的自我评价
2013/11/05 职场文书
个人优缺点自我评价
2014/01/27 职场文书
网上商城创业计划书范文
2014/01/31 职场文书
奥巴马连任演讲稿
2014/05/15 职场文书
做一个有道德的人活动实施方案
2014/08/23 职场文书
SQL Server查询某个字段在哪些表中存在
2022/03/03 SQL Server