【问题标题】:Python Sharing a network socket with multiprocessing.ManagerPython 与 multiprocessing.Manager 共享网络套接字
【发布时间】:2010-12-17 04:11:35
【问题描述】:

我目前正在编写一个nginx代理服务器模块,前面有一个请求队列,所以当nginx后面的服务器无法处理请求时,请求不会被丢弃(nginx被配置为负载均衡器)。

我正在使用

from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler

这个想法是在处理请求之前将请求放入队列中。我知道 multiprocessing.Queue 只支持简单对象,不能支持原始套接字,所以我尝试使用 multiprocess.Manager 来制作共享字典。 Manager 也使用套接字进行连接,所以这个方法也失败了。有没有办法在进程之间共享网络套接字? 这是代码的问题部分:

class ProxyServer(Threader, HTTPServer):

    def __init__(self, server_address, bind_and_activate=True):
        HTTPServer.__init__(self, server_address, ProxyHandler,
                bind_and_activate)

        self.manager = multiprocessing.Manager()

        self.conn_dict = self.manager.dict()
        self.ticket_queue = multiprocessing.Queue(maxsize= 10)
        self._processes = []
        self.add_worker(5)


    def process_request(self, request, client):
        stamp = time.time()
        print "We are processing"

        self.conn_dict[stamp] = (request, client) # the program crashes here


    #Exception happened during processing of request from ('172.28.192.34', 49294)
    #Traceback (most recent call last):
    #  File "/usr/lib64/python2.6/SocketServer.py", line 281, in _handle_request_noblock
    #    self.process_request(request, client_address)
    #  File "./nxproxy.py", line 157, in process_request
    #    self.conn_dict[stamp] = (request, client)
    #  File "<string>", line 2, in __setitem__
    #  File "/usr/lib64/python2.6/multiprocessing/managers.py", line 725, in _callmethod
    #    conn.send((self._id, methodname, args, kwds))
    #TypeError: expected string or Unicode object, NoneType found

        self.ticket_queue.put(stamp)


    def add_worker(self, number_of_workers):
        for worker in range(number_of_workers):
            print "Starting worker %d" % worker
            proc = multiprocessing.Process(target=self._worker, args = (self.conn_dict,))
            self._processes.append(proc)
            proc.start()

    def _worker(self, conn_dict):
        while 1:
            ticket = self.ticket_queue.get()

            print conn_dict
            a=0
            while a==0:
                try:
                    request, client = conn_dict[ticket]
                    a=1
                except Exception:
                    pass
            print "We are threading!"
            self.threader(request, client)

【问题讨论】:

    标签: python sockets networking process share


    【解决方案1】:

    你可以使用 multiprocessing.reduction 在进程之间传输连接和套接字对象

    示例代码

    # Main process
    from multiprocessing.reduction import reduce_handle
    h = reduce_handle(client_socket.fileno())
    pipe_to_worker.send(h)
    
    # Worker process
    from multiprocessing.reduction import rebuild_handle
    h = pipe.recv()
    fd = rebuild_handle(h)
    client_socket = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
    client_socket.send("hello from the worker process\r\n") 
    

    【讨论】:

    • 这是我一直在寻找的,它在 python 网站上没有很好的记录
    【解决方案2】:

    看起来你需要在进程之间pass file descriptors(假设这里是 Unix,不知道关于 Windows)。我从来没有在 Python 中这样做过,但这里是您可能想要检查的 python-passfd 项目的链接。

    【讨论】:

      【解决方案3】:

      您可以查看此代码 - https://gist.github.com/sunilmallya/4662837 这是 multiprocessing.reduction 套接字服务器,父处理在接受连接后将连接传递给客户端

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-24
        • 2013-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多