Поток Python 3.x висит на вызове join () - PullRequest
0 голосов
/ 14 октября 2019

У меня проблемы с зависанием потока, когда я вызываю join () для него. Я пытаюсь использовать протокол Go-back N для отправки / получения пакетов по сети, и я создал отдельный поток для обработки ACK, которые возвращаются с сервера.

У меня есть один поток, запущенный по этому методу, который проверяет входящие пакеты и получает номер ACK, а затем сохраняет этот номер в настройке переменной в init , которая называется self.lastAck. Упрощенная версия метода:

    #Anything not explicitly defined here is global variable
    def ack_check(self):
        ack_num = 0
        pktHdrData = '!BBBBHHLLQQLL'
        # Listening for ack number from server and store it in self.lastAck.
        while True:
            # variable also inside the __init__ method
            if (self.finish == 1):
                break
            data,address = sock.recvfrom(4096)
            clientAck = struct.unpack(pktHdrData,data)
            ackNumRecv = clientAck[9]
            self.lastAck = ackNumRecv

Упрощенная версия функции, которая создает поток и обрабатывает отправку клиентских пакетов:

    def send(self,buffer):

        # Assume packet header and all relevant data is set up correctly here
        # ...

        t1 = threading.Thread(target = self.ack_check, args=())
        t1.setDaemon = True
        t1.start()

        # All of this works perfectly and breaks as expected
        while True:
            # Packets/data get sent here and break when self.lastAck reaches a specific number. Assume this works properly and breaks


        self.finish = 1
        print("About to hang here")
        t1.join()
        return bytessent

Я в конечном итоге зависаю сразу после печатиAbout to end here и я не могу понять, почему. Я смогу заставить его работать, если я выйду из цикла while True в секции else, но затем я закончу тем, что закрою поток, прежде чем получу все номера ACK от получателя. Поэтому вместо полных 32 ACK я получу от 1 ACK до полных 32.

Я думаю, что проблема заключается в методе def ack_check(self), где он не выходит из цикла дажехотя это должно произойти после того, как я вызову self.finish = 1, но каждый раз он просто зависает.

Кроме того, нет ничего другого, кроме этих двух методов, вызывающих self.finish и self.lastAck. Я знаю о взаимоблокировке, но я не мог понять, как это возможно в этой ситуации.

Sidenote: Я понимаю, что протокол Go-Back N здесь вообще не реализован должным образом, но это был первый шаг, который я предпринял при его создании.

1 Ответ

0 голосов
/ 14 октября 2019

В соответствии с комментариями, вызов recvfrom в ack_check оставил поток висящим. Фиксированный код:

    def ack_check(self):
        ack_num = 0
        pktHdrData = '!BBBBHHLLQQLL'
        # Listening for ack number from server and store it in self.lastAck.
        while True:
            # variable also inside the __init__ method
            if (self.finish == 1):
                break
            sock.timeout(0.2)
            try:
                data,address = sock.recvfrom(4096)
            except socket.timeout:
                break
            clientAck = struct.unpack(pktHdrData,data)
            ackNumRecv = clientAck[9]
            self.lastAck = ackNumRecv
...