扭曲的`callInThread`正在阻塞

syn*_*ack 0 python networking multithreading asynchronous twisted

我有一个基于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()
Run Code Online (Sandbox Code Playgroud)

总结一下,该write_packet方法将调用transport.write我传递给构造函数类的某个协议实例的方法A.请注意,这是一个递归实现,其中方法send调用自身以获取通过协议发送的以下数据包.问题是,当它调用send延迟pkt.iat秒时,send的执行将在该callInThread调用时死亡,该调用应该生成一个新线程并继续执行do_some_stuff,对吧?所有这些代码实际上是在另一个扭曲的线程中运行,这意味着我们在某些时候从外部调用callInThread(packet_sender.send, pkt_0).

你有什么线索可能会发生什么吗?关于Twisted线程如何工作,我有什么遗漏吗?

Gly*_*yph 5

self.protocol.transport.write是反应堆中物体的方法.你不允许在非反应堆线程中调用此方法; 行为未定义.阻塞是做未定义事物的一个潜在结果.您也不允许在一个进程中拥有多个反应器线程.

关于线程的扭曲文档涵盖了这一点; 也许你应该检讨一下.你几乎肯定不需要使用线程来完成你想要做的事情(已经transport.write是非阻塞的,所以试图在一个线程中做这件事无论如何都无济于事); 如果您因为某些原因需要线程而未在此处显示,或许您应该提出一个更具体的问题,即如何避免它们执行该任务.