nic*_*ang 5 python zeromq pyzmq python-multiprocessing
请参阅下面的代码:
server.py
import zmq
import time
from multiprocessing import Process
class A:
def __init__(self):
ctx = zmq.Context(1)
sock = zmq.Socket(ctx, zmq.PUB)
sock.bind('ipc://test')
p = Process(target=A.run, args=(sock,))
p.start() # Process calls run, but the client can't receive messages
p.join() #
#A.run(sock) # this one is ok, messages get it to be received
@staticmethod
def run(sock):
while True:
sock.send('demo'.encode('utf-8'))
print('sent')
time.sleep(1)
if __name__ =='__main__':
a = A()
Run Code Online (Sandbox Code Playgroud)
client.py
import zmq
ctx=zmq.Context(1)
sock = zmq.Socket(ctx, zmq.SUB)
sock.connect('ipc://test')
sock.setsockopt_string(zmq.SUBSCRIBE, '')
while True:
print(sock.recv())
Run Code Online (Sandbox Code Playgroud)
在 的构造函数中server.py,如果我.run()直接调用 -method,客户端可以收到消息,但是当我使用 -method 时multiprocessing.Process(),会失败。谁能解释一下并提供一些建议吗?
Q : “为什么我使用ZeroMQ运行时通讯失败?”
multiprocessing.Process
好吧,ZeroMQ 并不是无法通信,问题是,Pythonmultiprocessing模块如何“操作”。
该模块的设计使得某些处理可以逃离 python 中央 GIL 锁(re [SERIAL]-iser,用作永远存在的[CONCURRENT]情况的主要避免器)。
这意味着对 的调用会生成multiprocessing.ProcessPython 解释器状态的一个精确“镜像副本”,“导出”到新的操作系统生成的进程中(详细信息取决于本地主机操作系统)。
鉴于此,“镜像”副本可以访问该方法已经获取的地址已经拥有的资源的可能性为零__main__,.bind()因此ipc://test“远程”进程永远不会获得接触此 ZeroMQ 接入点的“权限”,除非代码得到修复并完全重构。
问:“谁能解释一下并提供一些建议吗?”
当然。最好的开始步骤是充分理解垄断 GIL 锁重新化的 Pythonic 文化[SERIAL],其中不会有两件事同时发生,因此即使添加更多线程也不会加快处理流程,因为所有这些都由中央“垄断者”GIL 锁重新调整。
接下来,理解 Python 解释器状态的完全反映副本的承诺,虽然听起来很有希望,但也有一些明显的缺点 - 新进程作为“镜像”副本不能在已拥有的资源上引入冲突情况。如果他们尝试这样做,那么在这种主要设计不当的情况下,未按预期工作的情况是较温和的问题。
__main__在您的代码中,实例化中的第一行a = A(),其中A的.__init__方法直接占用自 以来的 IPC 资源.bind('ipc://test')。后面的步骤,p = Process( target = A.run, args = ( sock, ) )“镜像”——复制 python 解释器的状态(原样副本),并且不能不p.start()“拥有”与已经拥有的资源相同的资源__main__(是的,ipc://test对于“镜像”来说—— ed 进程指示调用以获取 ) 中相同的非自由资源.bind('ipc://test')。这永远不会飞。
最后但并非最不重要的一点是,享受 Zen-of-Zero,这是 Martin SUSTRIK 在分布式计算方面的杰作,它经过精心设计,可实现最终可扩展、几乎零延迟、非常舒适、广泛移植的信令和消息传递框架。
| 归档时间: |
|
| 查看次数: |
1369 次 |
| 最近记录: |