У меня проблемы с зависанием потока, когда я вызываю 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 здесь вообще не реализован должным образом, но это был первый шаг, который я предпринял при его создании.