簡體   English   中英

Python多處理管理器OSError“每個套接字地址只能使用一種”

[英]Python multiprocessing Manger OSError “Only one usage of each socket address”

我正在python(3.4.4)中創建一個通訊平台,並使用multiprocessing.managers.BaseManager類。 我已將問題隔離到下面的代碼中。

目的是讓ROVManager(role ='server')實例在主計算機上的一個進程中運行,並為在同一計算機上運行的多個ROVManager(role ='client')實例的系統字典提供讀/寫功能。連接到同一網絡的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

我的研究

while循環總數通常在15000-16000之間。 據我了解,每次調用mgr.system()。get('shutdown')時似乎都創建並終止了一個套接字。 然后,Windows用完了可用的套接字。 我似乎找不到設置socket.SO_REUSEADDR的方法

有沒有解決此問題的方法,或者不是經理專為這種溝通而設計的? 謝謝 :)

由於錯誤提示,通常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上創建兩個進程,因此出現錯誤。
您可以在這里參考以學習如何使用SO_REUSEADDR及其含義,但是我引用的主要部分應該可以幫助您前進

在調用與原始套接字相同的端口上的綁定之前,第二個套接字調用optname參數設置為SO_REUSEADDR且optval參數設置為布爾值TRUE的setsockopt。 成功綁定第二個套接字后,綁定到該端口的所有套接字的行為將不確定。 例如,如果同一端口上的所有套接字都提供TCP服務,則不能保證該端口上的任何傳入TCP連接請求都可以由正確的套接字處理-該行為是不確定的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM