from multiprocessing import Pool,freeze_support,Lock
import time
cnt=0
lock=Lock()
def test(item):
with lock:
global cnt
time.sleep(1)
cnt=cnt+1
if __name__=='__main__':
freeze_support()
start=time.time()
pool=Pool()
pool.map(test,range(0,10))
pool.close()
pool.join()
print(cnt)
print(time.time()-start)
用python开多进程执行某个test任务,test任务简化为一个延时操作,每进行一次test就让共享变量加1,使用了multiprocessing中的锁Lock()来解决数据竞争的问题,发现无法解决,每次print的cnt值还是0(如果成功解决数据竞争问题的话cnt最后应该是10),请问应该怎么改?
多线程共享变量一般这么写:
from multiprocessing import freeze_support,Lock,Process,Value
import time
cnt=Value('i',0)
lock=Lock()
def my_test(cnt,lock):
with lock:
time.sleep(1)
cnt.value+=1
print(cnt.value)
if __name__=='__main__':
freeze_support()
ps=[Process(target=my_test,args=(cnt,lock)) for i in range(10)]
start=time.time()
for p in ps:
p.start()
for p in ps:
p.join()
print(cnt.value)
print(time.time()-start)
建议:pool个人认为一般用相对独立的并行处理,个进程之间几乎没有交集,所以对于共享变量建议还是不要用pool,
还有就是,在windos系统下,pool对自定义的方法,一般会报错(需要将自定义的函数在另一个文件中定义,用import导入后使用),所以你的代码里其实各个子进程都没有执行,详情你可以在一个shell里边逐行
运行检查一下。
https://www.cnblogs.com/lsdb/p/10815319.html
第一个问题, test 传入的 item 元素没有使用,cnt=cnt+item 完成累加。
from multiprocessing import Pool,freeze_support,Lock
import time
cnt=0
lock=Lock()
def test(item):
with lock:
global cnt
time.sleep(1)
cnt=cnt+item
print(cnt)
第二个问题,可以看到累加过程,主线程得到的都是最初的0.太诡异了,不理解。
最近我也在研究这个。
可以明确说下,子进程是无法直接访问主进程数据的,因为 上下文环境不同。
官方有 Pioe 管道命令。 Menger() 服务。 Queue 队列。
你可以查看官方文档或者百度学习相关用法