我是新手,并尝试多次处理来控制全局计数器,但是下面的代码给出了global_counter'加入后为什么?为什么?!
from multiprocessing import Process, RLock
global_counter = 0
def counter(n, lock):
global global_counter
lock.acquire()
global_counter += n
lock.release()
def main(process_number):
lock = RLock()
pr_list = []
for i in xrange(process_number):
pr = Process(target=counter, args=(10, lock))
pr_list.append(pr)
for pr in pr_list:
pr.start()
for pr in pr_list:
pr.join()
if __name__ == '__main__':
main(10)
print global_counter # it's still 0...
答案 0 :(得分:0)
尝试使用multiprocessing.Value
对象。您可以使用以下实现删除RLock
对象:
from multiprocessing import Process, Value, Lock
def counter(n, shared_value, lock):
with lock:
shared_value.value += n
def main(process_number, shared_value):
pr_list, lock = [], Lock()
for i in xrange(process_number):
pr = Process(target=counter, args=(10, shared_value, lock))
pr_list.append(pr)
for pr in pr_list:
pr.start()
for pr in pr_list:
pr.join()
if __name__ == '__main__':
shared_counter = Value("i", 0)
main(10, shared_counter)
print shared_counter.value # 100
这是因为2个进程不共享内存。子进程将拥有自己的内存副本,并且不会更新原始的global_counter
变量。
但是,线程共享内存。
答案 1 :(得分:0)
threading
和multiprocessing
之间存在深刻的差异。
基本上,线程是同一进程的一部分,共享所有数据,而multiprocessing
使用的多个进程都有自己的数据(这是父进程的副本)新流程开始的那一刻)。因此每个子进程都有自己的独立global_counter
。在这种情况下,使用FunkySayu建议的Value
是一个很好的解决方案。
另一个值得关注的是,在CPython中,全局解释器锁强制执行,一次只有一个线程正在执行Python字节码。这意味着处理器密集型任务不会像预期的那样从线程中受益。将处理扩展到多个问题(使用multiprocessing
)可以避免此问题。另一方面,在单独的过程中进行的计算的结果通常必须被传送回父过程。根据数据的大小,这也有开销。