如何使多处理从列表中删除它自己

时间:2014-03-15 15:03:28

标签: python multiprocessing

我正在尝试创建一个使用多处理来处理客户端连接的服务器(当前是一个echo服务器)。

由于我希望能够在服务器出现故障时正确关闭与每个客户端的连接。我将所有连接添加到列表中,遗憾的是,我无法想到一种不会浪费时钟周期或在新客户端连接时更新列表的方法。从列表中删除已关闭的连接。

我很好,我将如何从列表中删除该过程,如下所示:

for i in xrange(len(sock.rProcesses)):
    if not sock.rProcesses[i].is_alive():
        del sock.rProcesses[i]

至于我的代码是:

from multiprocessing import Process
import socket, struct, sys, json
import settings

class ConnectionClient(Process):
    conn = None
    addr = None
    def __init__(self, connection):
        super(ConnectionClient, self).__init__()
        self.conn, self.addr = connection
        self.start()
        print 'Connected with ' + self.addr[0] + ':' + str(self.addr[1])

    def __send(self, info):
        print 'sending %s' % info
        self.conn.send(struct.pack('Q', len(info)))
        self.conn.recv(1)
        self.conn.send(info)

    def __recv(self):
        data = struct.unpack('Q', self.conn.recv(8))[0]
        self.conn.send(' ')
        return self.conn.recv(data)

    def _close(self):
        if self.conn != None:
            self.conn.close()
        print 'Disconnected with ' + self.addr[0] + ':' + str(self.addr[1])
        del self.conn, self.addr
        self.conn = None

    def run(self):
        while True:
            try:data = json.loads(self.__recv())
            except:break
            if data[0] == 'QUIT':
                break
            else:
                try:self.__send(json.dumps(data))
                except:break
        self._close()

#This is used by the with statement, so that I know that everything will close
#even if I ctrl-c in console.
class socketHandler(object):
    s = None
    rProcesses = []
    def __enter__(self):
        for res in socket.getaddrinfo(settings.host, settings.port,
                                      socket.AF_UNSPEC, socket.SOCK_STREAM, 0, 
                                      socket.AI_PASSIVE):
            af, socktype, proto, canonname, sa = res
            try:
                self.s = socket.socket(af, socktype, proto)
            except socket.error as msg:
                print msg
                self.s = None
                continue
            try:
                self.s.bind(sa)
                self.s.listen(1)
            except socket.error as msg:
                print msg
                self.s.close()
                self.s = None
                continue
            break
        return self
    def __exit__(self, type, value, traceback):
        print 'Closing Socket'
        if self.s != None:
            self.s.close()
        for i in self.rProcesses:
            if i.is_alive():
                i._close()
        del self.s

with socketHandler() as sock:
    if sock.s == None:
        print 'could not open socket'
        sys.exit(1)
    #Now I multithread the connections, not very well.
    while True:
        sock.rProcesses.append(ConnectionClient(sock.s.accept()))

我真的不知道在这里使用队列是一个好主意(我不知道他们做了什么)。我只能考虑使用多处理的while循环,或者在连接后检查,我个人也不想使用它们。或者我这样做是错的? (这是我的A2项目,所以我有点新手。)

服务器不允许在我的计算机上进行IPv4连接,因此如果您希望客户端和设置(只是本地主机和端口)在这里是一个链接:https://gist.github.com/Peilonrayz/ab693564145c53aa146c

0 个答案:

没有答案