我有一个如下的python程序
def send_request(data):
global lock
lock.acquire()
print(data)
lock.release()
if __name__ == '__main__':
data_list = ['data1', 'data2', 'data3']
lock = multiprocessing.Lock()
pool = multiprocessing.Pool(3)
pool.map(send_request, data_list)
pool.close()
pool.join()
为什么会发生此错误? NameError: name 'lock' is not defined.
在下面的答案中,@Jean-FrançoisFabre说,原因是“在运行子进程时,python是“ forking”,并且没有看到lock
声明,因为它没有执行__main__
属于子流程。”
但是在下面的示例中,子进程也不会看到lock
定义,但是为什么程序可以正常工作?
import multiprocessing
def send_request(data):
lock.acquire()
print(data,' ',os.getpid())
lock.release()
def init(l):
global lock
lock = l
if __name__ == '__main__':
data_list = ['data1', 'data2', 'data3']
lock = multiprocessing.Lock()
pool = multiprocessing.Pool(8, initializer=init, initargs=(lock,))
pool.map(send_request, data_list)
pool.close()
pool.join()
答案 0 :(得分:1)
在多处理的情况下,您还需要做更多的事情。
在运行子流程时,python是“ forking”并且看不到lock
声明,因为它没有执行子流程中的__main__
部分。
此外,在Windows(没有fork
的情况下,模拟了分支,与类似Unix的平台相比,导致了不同的行为:简而言之,fork
能够恢复新的进程从旧进程开始的地方开始,但是在Windows上,Python必须从头开始运行新进程并在之后进行控制,这会带来副作用)
您必须在__main__
测试之外将锁创建为全局变量(并且可以删除global
关键字,如果没有它,它将起作用)
import multiprocessing
lock = multiprocessing.Lock()
def send_request(data):
lock.acquire()
print(data)
lock.release()
通过这些修改,您的程序会打印
data1
data2
data3
符合预期。