weixin_41977332
星风雪宇
2020-04-25 19:46
采纳率: 50%
浏览 597

Python多进程修改共享变量的问题

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),请问应该怎么改?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • qq_39412061
    吃鸡王者 2020-04-26 14:37
    已采纳

    多线程共享变量一般这么写:

    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里边逐行
    运行检查一下。

    点赞 评论
  • dabocaiqq
    dabocaiqq 2020-04-25 23:50
    点赞 评论
  • wojiushiwo945you
    毕小宝 2020-04-26 07:29

    第一个问题, 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.太诡异了,不理解。

    点赞 评论

相关推荐