sti*_*eta 5 python multiprocessing
我正在研究工作人员的 multiprocessing.Pool ,试图用某种状态初始化工作人员。池可以接受一个可调用的、初始化的,但它不会传递对已初始化工作程序的引用。我见过的几个例子使用它调用全局变量,这看起来真的很讨厌。
有没有什么好方法可以使用 multiprocessing.Pool 初始化工作状态?
编辑:一个例子:
我有工人,每个工人都做了一些相对昂贵的初始化(绑定到套接字),我不想每次都这样做。我可以手动初始化我的套接字,然后在我分配工作时将它们传递进来,但是跨进程共享文件描述符很复杂,如果不是不可能的话。所以每次我想处理一个请求时,我都必须初始化和绑定。
从技术上讲,正确的做法是将初始化函数的结果作为参数传递给 worker 执行的每个函数。
在这种情况下,拥有全局变量也是正确和安全的,因为通过构造它们会导致私有对象存在于不同进程的不同域中。
我的一般建议是使用合理的可重入编程风格构建函数,并在利用multiprocessing功能的同时允许使用全局变量。
保留您的示例,以下send函数需要一些上下文(在本例中为socket):
def send(socket, data):
pass # ... your code here
return dust
Run Code Online (Sandbox Code Playgroud)
为方便起见,worker 执行的初始化代码和基本代码将依赖于全局变量。
socket = None
def init(address, port):
global socket
socket = magic(address, port)
def job(data):
global socket
assert socket is not None
return send(socket, data)
pool = multithreading.Pool(N, init, [address, port])
pool.map(job, ['foo', 'bar', 'baz'])
Run Code Online (Sandbox Code Playgroud)
通过以这种方式对其进行编码,无需多处理即可对其进行简单和自然的测试。您可以将全局状态视为一个完全安全的上下文胶囊。
作为额外的方便点,请记住,multiprocessing它不太擅长发送复杂的数据(例如回调)。最好的方法是发送简单的数据片段(字符串、列表、字典collections.namedtuple等)并在工作端重建复杂的数据结构(使用初始化函数)。