我正在python(3.4.4)中创建一个通信平台并使用 multiprocessing.managers.BaseManager 类。我已将问题与以下代码隔离开来。
目的是在主计算机上的一个进程中运行 ROVManager(role =' server')实例,并为系统提供读/写功能字典用于在同一台计算机上运行的多个 ROVManager(角色='客户端')实例和连接到同一网络的ROV(远程操作的车辆)。这样,多个客户端/进程可以执行不同的任务,例如读取传感器值,移动电机,打印,记录等,所有这些都使用相同的字典。下面的 start_reader()就是其中一个客户端。
from multiprocessing.managers import BaseManager
import multiprocessing as mp
import sys
class ROVManager(BaseManager):
def __init__(self, role, address, port, authkey=b'abc'):
super(ROVManager, self).__init__(address=(address, port),
authkey=authkey)
if role is 'server':
self.system = {'shutdown': False}
self.register('system', callable=lambda: self.system)
server = self.get_server()
server.serve_forever()
elif role is 'client':
self.register('system')
self.connect()
def start_server(server_ip, port_var):
print('starting server')
ROVManager(role='server', address=server_ip, port=port_var)
def start_reader(server_ip, port_var):
print('starting reader')
mgr = ROVManager(role='client', address=server_ip, port=port_var)
i = 0
while not mgr.system().get('shutdown'):
sys.stdout.write('\rTotal while loops: {}'.format(i))
i += 1
if __name__ == '__main__':
server_p = mp.Process(target=start_server, args=('0.0.0.0', 5050))
reader_p = mp.Process(target=start_reader, args=('127.0.0.1', 5050))
server_p.start()
reader_p.start()
while True:
# Check system status, restart processes etc here
pass
这会导致以下输出和错误:
starting server
starting reader
Total while loops: 15151
Process Process - 2:
Traceback(most recent call last):
File "c:\python34\Lib\multiprocessing\process.py", line 254, in _bootstrap
self.run()
File "c:\python34\Lib\multiprocessing\process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "C:\git\eduROV\error_test.py", line 29, in start_reader
while not mgr.system().get('shutdown'):
File "c:\python34\Lib\multiprocessing\managers.py", line 640, in temp
token, exp = self._create(typeid, *args, **kwds)
File "c:\python34\Lib\multiprocessing\managers.py", line 532, in _create
conn = self._Client(self._address, authkey=self._authkey)
File "c:\python34\Lib\multiprocessing\connection.py", line 496, in Client
c = SocketClient(address)
File "c:\python34\Lib\multiprocessing\connection.py", line 629, in SocketClient
s.connect(address)
OSError: [WinError 10048] Only one usage of each socket address(protocol / network address / port) is normally permitted
总循环次数通常在15000-16000范围内。根据我的理解,每次 mgr.system()时都会创建并终止套接字。调用get(' shutdown')。 Windows然后用完了可用的套接字。我似乎找不到设置 socket.SO_REUSEADDR 的方法。
有没有办法解决这个问题,或者不是为这种沟通做出的管理者?谢谢:))
答案 0 :(得分:0)
正如错误提示Only one usage of each socket address
一般,您可以/应该只将一个进程绑定到套接字(除非您通过在创建套接字时传递SO_REUSEADDR
选项来相应地设计应用程序)
。这些行
server_p = mp.Process(target=start_server, args=('0.0.0.0', 5050))
reader_p = mp.Process(target=start_reader, args=('127.0.0.1', 5050))
在同一个端口5050
上创建两个进程&所以错误。
您可以参考here了解如何使用SO_REUSEADDR
&它的含义,但我引用的主要部分应该让你去
第二个套接字调用setsockopt并将optname参数设置为 SO_REUSEADDR和optval参数设置为布尔值TRUE 在与原始套接字相同的端口上调用bind之前。一旦 第二个套接字已成功绑定,所有套接字的行为 绑定到该端口是不确定的。例如,如果所有的 同一端口上的套接字提供TCP服务,任何传入的TCP 无法保证通过端口的连接请求得到处理 通过正确的套接字 - 行为是不确定的。