如何将经理对象传递给进程

时间:2017-02-26 21:34:34

标签: python multiprocessing python-multiprocessing file-locking

我试图将整个manger对象传递给进程,但我无法这样做。当我尝试收到此错误时:

Traceback (most recent call last):
  File "TwitchMarketDatabase.py", line 46, in <module>
    multiprocessing.Process(target=accept_thread, args=(SERVER, M)).start()
  File "C:\Program Files\Python36\lib\multiprocessing\process.py", line 105, in start
    self._popen = self._Popen(self)
  File "C:\Program Files\Python36\lib\multiprocessing\context.py", line 223, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "C:\Program Files\Python36\lib\multiprocessing\context.py", line 322, in _Popen
    return Popen(process_obj)
  File "C:\Program Files\Python36\lib\multiprocessing\popen_spawn_win32.py", line 65, in __init__
    reduction.dump(process_obj, to_child)
  File "C:\Program Files\Python36\lib\multiprocessing\reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
  File "C:\Program Files\Python36\lib\multiprocessing\connection.py", line 939, in reduce_pipe_connection
    dh = reduction.DupHandle(conn.fileno(), access)
  File "C:\Program Files\Python36\lib\multiprocessing\connection.py", line 170, in fileno
    self._check_closed()
  File "C:\Program Files\Python36\lib\multiprocessing\connection.py", line 136, in _check_closed
    raise OSError("handle is closed")
OSError: handle is closed

C:\projects\twitch-market>pause
Press any key to continue . . . Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Program Files\Python36\lib\multiprocessing\spawn.py", line 99, in spawn_main
    new_handle = reduction.steal_handle(parent_pid, pipe_handle)
  File "C:\Program Files\Python36\lib\multiprocessing\reduction.py", line 82, in steal_handle
    _winapi.PROCESS_DUP_HANDLE, False, source_pid)
OSError: [WinError 87] The parameter is incorrect

我试图建立一个连接到python程序的处理程序,该程序使用进程并发写入文件,除非有人写入。我想这是一种非常愚蠢的做法,但我没有看到任何其他方式。所以我打算使用M(manager)对象为每个文件生成锁,如果它被写入的话。然后我会将锁添加到字典中。这就是我需要将M传递给accept连接线程的原因。正如我所说,这是一种非常复杂和愚蠢的做法,我愿意接受有关我可以使用的建议。

if __name__ == '__main__':
    SERVER = socket.socket()
    SERVER.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    SERVER.bind(('127.0.0.1', 9988))
    M = multiprocessing.Manager()
    M.queues = M.dict()
    multiprocessing.Process(target=accept_thread, args=(SERVER, M)).start()
    print('Server Started.')
    input()

1 个答案:

答案 0 :(得分:1)

您不能将套接字对象作为参数传递给进程。您需要将代理引用传递给可变的内存对象,以在流程及其起源之间进行通信。

您可以通过多种方式来实现此目标:

  1. 使用管理器创建管道,将引用传递给流程。将过程写入管道,并在起源中接收该数据。如果您需要将原始数据从流程传递到起源,这是最好的方法。

  2. 创建队列并将内容添加到队列。另一端收到它。

  3. 创建一个类似文件的对象,并将其放在管理器创建的名称空间中。将名称空间引用作为参数传递给流程。

如果您需要将该数据传递给另一个进程,则仍然可以将其通过创建的套接字传递。但是,对于这种情况,最好是在进程内部 中实际创建一个套接字对象,然后直接与所需的打开套接字进行通信。

如果您的进程跨网络,则可以采用更复杂的方法,例如,建立一个跨网络管理器,该管理器的工作方式类似于带有套接字的其余服务器,并且将进程构建在顶部。但是,如果您只需要在由同一文件运行的流程和创始流程之间进行通信,则不需要这样做。