0

これには非常に簡単な解決策があると確信しています。どこを探すべきかわかりません。

私は次のようにする1つの方法を持っています:

 @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 のすべてのインスタンスは同じグローバル データで動作します。

私の問題は今、どうすればこれを同期できますか? 現状では、Clientthreads の 1 つが他にいくつの Clientthreads があるかを知る方法はありません。技術的には、0 以降の任意の数にすることができます。

これを解決する簡単な方法はありますか

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 に答える