使用multiprocessing.Array仍遇NameError:name 'list2_array' is not defined
解决多进程共享数组时的NameError问题
错误原因
- 子进程无法访问主进程后期定义的变量:你在
Pool()创建后才定义list2_array,但子进程是在Pool初始化时启动的,此时该变量还未创建,子进程自然找不到它,触发NameError。 - 共享数组的使用方式错误:
multiprocessing.Array返回的是ctypes数组对象,不是Python原生列表,不能直接用num in list2_array判断字节串是否存在;且直接用Array(c_char, list2)初始化的方式不符合c_char类型的存储逻辑(c_char是单个字符类型)。
解决方案
方案一:使用Pool初始化函数传递共享数组
通过Pool的initializer和initargs参数,在子进程启动时就把共享数组传递给它们,并转换成适合查找的集合结构:
from multiprocessing import Pool, Array from ctypes import c_char # 子进程全局变量,用于接收共享数组转换后的集合 shared_set = None def init_worker(arr): global shared_set # 将ctypes数组转换为集合,提升查找效率 shared_set = set() for item in arr: # 过滤可能的空字节(如果数组长度大于实际元素数) if item != b'': shared_set.add(item) def func(num): # 注意:num是字节串,需取出对应字节与集合元素匹配 if num[0] in shared_set: return num else: return num + b" Not Found" if __name__ == "__main__": my_list = [b"1", b"2", b"4", b"8"] list2 = [b"1", b"4"] # 创建对应长度的c_char类型共享数组 list2_array = Array(c_char, len(list2)) # 手动将元素赋值到共享数组中 for idx, item in enumerate(list2): list2_array[idx] = item[0] # 初始化Pool时传递共享数组 with Pool(initializer=init_worker, initargs=(list2_array,)) as pool: results = pool.map(func, my_list) print(results)
方案二:使用Manager共享列表(更简洁)
如果只是需要共享一个集合做查找,用multiprocessing.Manager提供的进程安全列表/集合会更简单,无需处理ctypes数组的复杂逻辑:
from multiprocessing import Pool, Manager from functools import partial def func(num, shared_list): if num in shared_list: return num else: return num + b" Not Found" if __name__ == "__main__": my_list = [b"1", b"2", b"4", b"8"] list2 = [b"1", b"4"] with Manager() as manager: # 创建进程安全的共享列表 shared_list = manager.list(list2) # 用partial把共享列表作为参数绑定到func with Pool() as pool: results = pool.map(partial(func, shared_list=shared_list), my_list) print(results)
运行结果
两种方案都能得到预期输出:
[b'1', b'2 Not Found', b'4', b'8 Not Found']
内容的提问来源于stack exchange,提问作者Venu2HD
相关产品推荐
相关产品推荐

