2015-04-21 58 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已經是非阻塞,所以試圖在線程中做到這一點無論如何也無濟於事);如果您因爲某些原因而不需要線程,那麼您可能應該提出一個更具體的關於如何避免這些任務的問題。

+0

我在文檔中找不到反應器和非反應器線程的定義。只是爲了看看我是否理解正確,是否意味着'reactor.callInThread()'會產生一個反應器線程(反應器是「reactor」)?謝謝 – synack