多文件Python进程间共享锁问题:API调用时出现NameError
解决多进程跨文件锁访问的NameError问题
问题根源
你在init_pool里初始化的lock是main模块的全局变量,但file2.py中的make_call函数访问的是自身模块的全局命名空间,两者不共享,所以会出现NameError: name 'lock' is not defined。
可行解决方案
方案1:显式传递锁作为参数(推荐)
避免依赖全局变量,直接将锁传递到需要调用的函数中,逻辑更清晰且不易出错:
main.py
import file2 from functools import partial from multiprocessing import Pool, Lock def evaluate_entry_of_list(lock, entry): response = file2.get_data(lock, entry) # 你的计算逻辑 return results if __name__ == '__main__': # 避免用list作为变量名,覆盖内置类型 entry_list = apicaller.get_list() t_lock = Lock() # 用partial绑定锁到函数参数 func_with_lock = partial(evaluate_entry_of_list, t_lock) with Pool(8) as pool: results = pool.map(func_with_lock, entry_list) process_results(results)
file2.py
import requests def get_data(lock, entry): # 假设这里是你准备url和body的逻辑 url = "你的API地址" body = {"entry": entry} return make_call(lock, url, body) def make_call(lock, url, body) -> requests.Response: # 用with语句自动管理锁的获取和释放,避免异常导致锁未释放 with lock: # 执行API调用 response = requests.post(url, json=body) return response
方案2:初始化file2模块的全局锁
在进程初始化时,将锁赋值给file2模块的全局变量,让make_call能直接访问:
main.py
import file2 from multiprocessing import Pool, Lock def evaluate_entry_of_list(entry): response = file2.get_data(entry) # 你的计算逻辑 return results def init_pool(given_lock): # 给file2模块的全局lock赋值 file2.lock = given_lock if __name__ == '__main__': entry_list = apicaller.get_list() t_lock = Lock() with Pool(8, initializer=init_pool, initargs=(t_lock,)) as pool: results = pool.map(evaluate_entry_of_list, entry_list) process_results(results)
file2.py
import requests # 先声明全局lock变量 lock = None def get_data(entry): url = "你的API地址" body = {"entry": entry} return make_call(url, body) def make_call(url, body) -> requests.Response: with lock: response = requests.post(url, json=body) return response
注意事项
- 永远不要用
list作为变量名,会覆盖Python内置的list类型,引发潜在问题。 - 使用
with lock:代替手动acquire()和release(),可以确保即使API调用抛出异常,锁也能被正确释放,避免死锁。
内容的提问来源于stack exchange,提问作者DIO BRANDO
相关产品推荐
相关产品推荐

