在多处理过程中保持统一计数?

发布于 2021-01-29 15:00:42

我有一个运行蒙特卡罗模拟的python程序,以找到概率问题的答案。我正在使用多重处理,这是伪代码

import multiprocessing

def runmycode(result_queue):
    print "Requested..."
    while 1==1:
       iterations +=1
    if "result found (for example)":
        result_queue.put("result!")

    print "Done"

processs = []
result_queue = multiprocessing.Queue()

for n in range(4): # start 4 processes
    process = multiprocessing.Process(target=runmycode, args=[result_queue])
    process.start()
    processs.append(process)

print "Waiting for result..."

result = result_queue.get() # wait

for process in processs: # then kill them all off
    process.terminate()

print "Got result:", result

我想扩展此范围,以便可以对已运行的迭代次数进行统一计数。就像线程1运行了100次,线程2运行了100次一样,我想显示总共200次迭代,作为控制台打印。我指的iterations是线程过程中的变量。如何确保所有线程都添加到同一变量?我认为使用的Global版本iterations会行得通,但行不通。

关注者
0
被浏览
49
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    普通全局变量不像线程之间共享那样在进程之间共享。您需要使用流程感知的数据结构。对于您的用例,amultiprocessing.Value应该可以正常工作:

    import multiprocessing
    
    def runmycode(result_queue, iterations):
       print("Requested...")
       while 1==1: # This is an infinite loop, so I assume you want something else here
           with iterations.get_lock(): # Need a lock because incrementing isn't atomic
               iterations.value += 1
       if "result found (for example)":
           result_queue.put("result!")
    
       print("Done")
    
    
    if __name__ == "__main__":
        processs = []
        result_queue = multiprocessing.Queue()
    
        iterations = multiprocessing.Value('i', 0)
        for n in range(4): # start 4 processes
            process = multiprocessing.Process(target=runmycode, args=(result_queue, iterations))
            process.start()
            processs.append(process)
    
        print("Waiting for result...")
    
        result = result_queue.get() # wait
    
        for process in processs: # then kill them all off
            process.terminate()
    
        print("Got result: {}".format(result))
        print("Total iterations {}".format(iterations.value))
    

    一些注意事项:

    1. 我明确将传递Value给子代,以保持代码与Windows兼容,Windows无法在父代和子代之间共享读/写全局变量。
    2. 我用锁保护了增量,因为它不是原子操作,并且容易受到竞争条件的影响。
    3. if __name__ == "__main__":再次添加了一个保护措施,以帮助与Windows兼容,并作为一般的最佳实践。


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看