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

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

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

4条回答 默认 最新

  • 吃鸡王者 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 2020-04-25 23:50
    评论
    解决 无用
    打赏 举报
  • 毕小宝 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.太诡异了,不理解。

    评论
    解决 无用
    打赏 举报
  • PandaQk 2021-11-01 00:22

    最近我也在研究这个。
    可以明确说下,子进程是无法直接访问主进程数据的,因为 上下文环境不同。

    官方有 Pioe 管道命令。 Menger() 服务。 Queue 队列。
    你可以查看官方文档或者百度学习相关用法

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题