2015-04-21 2 views
0

у меня на основе витой программы, которые я упрощены в следующем отрывке:Витая `callInThread` блокирует

class PacketSender(object): 

     def __init__(self, protocol_instance): 
      self._stop = False 
      self._protocol = protocol_instance 

     def send(self, pkti): 
      try: 
       pkti1 = gen_packets.next() 
       reactor.callInThread(self.write_packet, pkti) 
      except StopIteration: 
       self._stop = True 

      do_some_stuff() 

      if not self._stop: 
       reactor.callLater(pkti.iat, self.send, pkti1) 

     def write_packet(self, pkt): 
      self.protocol.transport.write(pkt) 
    ... 
reactor.run() 

Резюмируя много, метод write_packet будет вызывать transport.write метод определенного экземпляра протокола у меня есть передается классу конструктора A. Обратите внимание, что это рекурсивная реализация, где метод send вызывает себя, чтобы получить следующий пакет для отправки по протоколу. Проблема в том, что когда он называет send задержкой pkt.iat секунд, выполнение отправки будет умирать при вызове callInThread, в котором должен появиться новый поток и продолжить выполнение do_some_stuff, правильно? Весь этот код фактически работает в другом скрученном потоке, что означает, что в какой-то момент мы вызываем извне callInThread(packet_sender.send, pkt_0).

У вас есть какие-либо сведения о том, что может произойти? Есть ли что-то, что мне не хватает в том, как работают витые нити?

ответ

5

self.protocol.transport.write - метод на объекте в реакторе. Вы не можете назвать этот метод в нереакторной нити; поведение не определено. Блокировка - один из потенциальных результатов выполнения неопределенных вещей. Вам также не разрешается иметь более одного потока реакторов в процессе.

The twisted documentation on threading охватывает это; возможно, вам стоит его просмотреть. Вам почти наверняка не нужно использовать потоки вообще для того, что вы пытаетесь сделать (transport.write is уже неблокирование, поэтому попытка сделать это в потоке не помогла бы); если вам нужны потоки по какой-то причине, не показанные здесь, возможно, вы должны задать более конкретный вопрос о том, как избежать их для этой задачи.

+0

Не удалось найти определение реакторных и нереакторных потоков в документации. Просто, чтобы понять, правильно ли я понял, означает ли это, что «реактор.callInThread()» будет порождать реакторную нить (где реактор «реактор»)? спасибо – synack

Смежные вопросы