0

我确信有一个非常简单的解决方案 - 我只是不知道在哪里寻找它。

我有一种方法如下:

 @staticmethod  
def serverstart(self):
    '''
    This binds the serverobject to a port (here: 50001) and creates a list of clients.
    For each client, a new clientthread object is created. There exist two different lists, one for the 
    sockets (literally) and one for the clientthreads
    '''
    logging.getLogger(__name__).info("Servergestartet(Verbindung usw)") 
    self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    self.server.bind(("", 50001)) 
    self.server.listen(1)
    #the list for the sockets
    self.clients = []
    #the list for the clientthreads
    self.clientthreads = []
    #hallo = "hallo" 
    self.clientnumber = 0          

    try: 
        while True: 
            lesen, schreiben, oob = select.select([self.server] + self.clients, 
                                         [], [])

            for sock in lesen: 
                if sock is self.server: 
                    client, addr = self.server.accept() 
                    myclient = clientthread.Clientthread(client, self.clientnumber, self)
                    self.clientnumber= self.clientnumber+1
                    myclient.start()
                    self.clients.append(client) 
                    self.clientthreads.append(myclient)
                    print "+++ Client %s verbunden" % addr[0] 
                #else: 
                    #nachricht = sock.recv(1024) 
                    #ip = sock.getpeername()[0] 
                    #if nachricht: 
                        #print "[%s,%d] %s" % (ip, self.clients.index(sock),nachricht) 
                    #else: 
                        #print "+++ Verbindung zu %s beendet" % ip 
                        #sock.close() 
                        #self.clients.remove(sock) 
    finally:
        logging.getLogger(__name__).info("serverstart ist durchgelaufen")

因此,每当有新客户端连接时,就会创建一个新的 Clientthread 实例。

Clientthread 现在继承自 Threading:

class Clientthread(threading.Thread):

   def __init__(self,clientsocket, clientnumber, server):

         threading.Thread.__init__(self)


       def run(self):
    from modules.logic import game
    '''
    as clientthread inherits from threading.Thread, this is this Thread's run-method.
    All it does is start the thread with the processkeysmethod - by now.
    '''
    logging.getLogger(__name__).info("Runmethode des Clientsockets läuft")
    logging.getLogger(__name__).info("Daten aus dem Client werden verarbeitet")


    while True:
        try:
            Clientthread.prepareDataforClient(self)
            Clientthread.processkeys(self)
        except Exception as e:
            print e

现在,当然每个 Clientthread 实例都在同一个全局数据上工作。

我的问题是现在,我该如何同步呢?事实上,其中一个客户端线程无法知道还有多少其他客户端线程 - 从技术上讲,它可以是从零开始的任何数字。

有没有简单的方法来解决这个问题

4

1 回答 1

0

您需要一个互斥锁来同步线程对共享资源的访问。然后,您可以像这样使用互斥锁:

with mtx:
    # access shared data

也就是说,还有几个问题:

  • 您究竟需要什么并不是 100% 清楚的。如果 RLock 解决了您的问题,那么这与您正在编写而不只是阅读的陈述有何对应?
  • 此外,请稍微清理一下您的代码,删除不必要的内容,例如注释代码。
  • 缩进是关闭的,这在 Python 中是一种罪过。
  • @staticmethod 的使用很奇怪。
  • 调用ClassName.function(self)可能最好写成self.function().
  • 使用 super() 调用基类的 init 函数。
  • 如果您在客户端和客户端线程之间有 1:1 的关系,那么通过将它们聚合在一个公共类中可以更好地建模。

最后,我不确定我是否能正确解释这一点,我宁愿不从 Thread 派生。对象不是线程,而是代表一个,类似于文件。创建一个将创建一个线程,但例如销毁一个不会停止线程,因此我发现推导不自然。然后看起来像这样:

s = accept(...)
th = threading.Thread(target=connection_handler_function, args=(s,))
th.daemon = True # you probably want that
th.start()
于 2013-02-16T23:41:16.943 回答