Как прекратить прослушивание при выполнении условия моей пустой очереди?

#python #multithreading #sockets

#python #многопоточность #сокеты

Вопрос:

У меня есть следующий код. У меня есть сервер, на котором есть рабочая очередь. Рабочие клиенты будут подключаться к этому серверу. Как только они будут подключены, они будут отправлены в отдельный поток, где им будет назначена работа. Этот поток будет повторно назначать работу, пока очередь не опустеет. Как только очередь опустеет, поток и клиент завершат работу.

Моя проблема в том, что основной поток также должен завершиться после завершения работы очереди. Я не могу заставить его сделать это. Основной поток пока выглядит следующим образом:

 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(),port))
s.listen()

thread_list = list()

while(True):
    if(not work_queue.empty()):
        conn, addr = s.accept()
    else:
        for thread in thread_list:
            thread.join()
        print('Program done. Bye!') 
        break
    print('Accepted a connection from ' str(addr))
    new_thread = threading.Thread(target=assign_task, args=(conn, addr))
    thread_list.append(new_thread)
    new_thread.start()
  

Мой основной поток застревает в accept, даже если я проверяю, пуста ли очередь. Как мне отключить его, когда рабочая очередь пуста?

Приветствуется любая помощь.

Ответ №1:

Попробуйте использовать settimeout(). Вы можете установить время ожидания сокета на сколь угодно долгое время в секундах, и когда ничто не подключается к серверу в это установленное время, это выдаст ошибку. Затем вы можете использовать try / except для выхода из кода. Это можно было бы сделать следующим образом:

 if(work_queue.empty()):
        s.settimeout(10) #set timeout to 10 seconds if work_queue.empty() returns true
try:
    conn, addr = s.accept()
except socket.timeout: #if the socket times out
    for thread in thread_list:
        thread.join()
    print('Program done. Bye!') 
    break

  

Это, конечно, будет внутри вашего основного цикла, заменяя ваш текущий оператор if / else