Простая многопоточная серверная клиентская программа - PullRequest
0 голосов
/ 23 февраля 2020

У меня есть многопоточные серверные и клиентские программы для простой игры. Всякий раз, когда клиент покидает игру, я пытаюсь поймать исключение с помощью try catch «кроме BrokenPipeError» и сообщаю об этом другим игрокам. Я также хочу завершить выходной поток клиента; Тем не менее, я беру ввод, такой как это:

while True:
            client = serverSocket.accept()
            t = ServerThread(client)
            t.start()

Я попытался использовать событие многопоточности с функцией stop (); однако я считаю, что не могу использовать оператор .join для выхода из потока из-за способа ввода данных. Как я должен положить конец силе на выходе клиента. Я знаю, что многопроцессорная библиотека имеет функцию завершения, но я также обязан использовать библиотеку потоков. Я попытался os_exit (1), но я считаю, что эта команда убивает весь процесс. Каков стандартный процесс выхода для таких программ, как эта?

1 Ответ

0 голосов
/ 23 февраля 2020

Прежде всего join() ничего не делать, но ожидает остановки потока. Поток останавливается, когда достигает конца подпрограммы с резьбой. Например,

class ServerThread(threading.Thread):

   def __init__(self,client,name):
      super().__init__(self)
      self.client = client
      self.name = name

   def inform(self,msg):
      print("{}: got message {}".format( self.name, msg ))
      self.client[0].send(msg)

   def run(self):
      while True:
         try:
            self.client[0].recv(1024)
         except BrokenPipeError: #client exits
            # do stuff
            break # -> ends loop
      return # -> thread exits, join returns

Если вы хотите сообщить другим клиентам, что кто-то уходит, я бы сделал еще один поток мониторинга

class Monitoring(threading.Thread):

   def __init__(self):
      super().__init__(self,daemon=True) # daemon means thread stops when main thread do
      self.clients=[]

   def add_client(self,client):
      self.clients.append(client)

   def inform_client_leaves(self,client_leaved):
      for client in self.clients:
         if client.is_alive():
            client.inform("Client '{}' leaves".format(client_leaved.name))

   def run(self):
      while True:
         for thread in list(self.threads):
            if not thread.is_alive(): # client exited
               self.threads.remove(thread)
               self.inform_client_exits(thread)
         time.sleep(1)

Таким образом, исходный код будет выглядеть как

mon = Monitoring()
mon.start()
while True:
        client = serverSocket.accept()
        t = ServerThread(client,"Client1")
        t.start()
        mon.add_client(t)
...