NameError:名称“锁”未定义

时间:2019-09-09 12:33:49

标签: python-3.x

我有一个如下的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()

1 个答案:

答案 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

符合预期。