扭曲的“callInThread”正在阻塞
Twisted `callInThread` is blocking
我有一个基于 Twisted 的程序,我在以下摘录中进行了简化:
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
方法classA
。请注意,这是一个递归实现,其中方法 send
调用自身以获取要通过协议发送的以下数据包。问题是,当它调用 send
延迟 pkt.iat
秒时,发送的执行将在那个 callInThread
调用时终止, 应该产生一个新线程并继续随着 do_some_stuff
的执行,对吧?所有这些代码实际上 运行 在另一个扭曲的线程中,这意味着在某些时候我们从外部调用 callInThread(packet_sender.send, pkt_0)
.
关于可能发生的事情,您有任何线索吗?关于 Twisted 线程的工作原理,我是否遗漏了什么?
self.protocol.transport.write
是反应器中对象的方法。不允许在非反应器线程中调用此方法;行为未定义。阻塞是做未定义事情的一个潜在结果。您也不允许在一个进程中拥有多个反应器线程。
The twisted documentation on threading涵盖了这个;也许你应该回顾一下。您几乎可以肯定根本不需要为您尝试做的事情使用线程(transport.write
是 已经 非阻塞所以尝试在线程中执行它不会无论如何帮助);如果您出于某种原因需要线程,此处未显示,也许您应该询问一个更具体的问题,了解如何在该任务中避免使用线程。
我有一个基于 Twisted 的程序,我在以下摘录中进行了简化:
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
方法classA
。请注意,这是一个递归实现,其中方法 send
调用自身以获取要通过协议发送的以下数据包。问题是,当它调用 send
延迟 pkt.iat
秒时,发送的执行将在那个 callInThread
调用时终止, 应该产生一个新线程并继续随着 do_some_stuff
的执行,对吧?所有这些代码实际上 运行 在另一个扭曲的线程中,这意味着在某些时候我们从外部调用 callInThread(packet_sender.send, pkt_0)
.
关于可能发生的事情,您有任何线索吗?关于 Twisted 线程的工作原理,我是否遗漏了什么?
self.protocol.transport.write
是反应器中对象的方法。不允许在非反应器线程中调用此方法;行为未定义。阻塞是做未定义事情的一个潜在结果。您也不允许在一个进程中拥有多个反应器线程。
The twisted documentation on threading涵盖了这个;也许你应该回顾一下。您几乎可以肯定根本不需要为您尝试做的事情使用线程(transport.write
是 已经 非阻塞所以尝试在线程中执行它不会无论如何帮助);如果您出于某种原因需要线程,此处未显示,也许您应该询问一个更具体的问题,了解如何在该任务中避免使用线程。