Python多处理Manger OSError"每个套接字地址只有一种用法"

时间:2018-02-09 14:01:23

标签: python multiprocessing-manager

我正在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 的方法。

有没有办法解决这个问题,或者不是为这种沟通做出的管理者?谢谢:))

1 个答案:

答案 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   无法保证通过端口的连接请求得到处理   通过正确的套接字 - 行为是不确定的。