You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python多进程报错NameError: name 'lock' is not defined的原因及疑问

Why does the second multiprocessing code run without errors while the first throws a NameError?

Great question! Let's break down why your first code fails and the second one works perfectly, focusing on how Python's multiprocessing handles shared resources and child process initialization.

The Problem with Your First Code

Let's look at the problematic snippet first:

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()

When you create a Pool of processes, each child process behaves in one of two ways depending on your OS:

  • On Unix-like systems: The child is forked from the parent, but it doesn't re-run the __main__ code block. Since your lock variable is defined inside __main__, the child process never gets a reference to it—so the global lock that send_request tries to access doesn't exist.
  • On Windows: The child process starts fresh, re-imports your script, and skips the __main__ block entirely (to avoid infinite spawning loops). Again, the lock variable is never initialized in the child's context.

Either scenario leads to the NameError: name 'lock' is not defined when send_request runs in a child process.

Why the Second Code Works

Now let's look at your working example (note: I added the missing os import to avoid another error):

import multiprocessing
import os

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()

The magic here is the Pool's initializer and initargs parameters:

  • Every time a child process is created in the pool, it immediately runs the initializer function (init) with the arguments passed in initargs (your shared lock object).
  • The init function sets the global lock variable in the child process to the valid lock object from the parent.

By the time send_request runs in the child, the global lock is already initialized and points to a working shared lock. This approach is cross-platform safe because it explicitly sets up required resources in each child, instead of relying on variables that only exist in the parent's __main__ block.


内容的提问来源于stack exchange,提问作者inaMinute

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:31:30