2017-10-05 94 views
0

我有一个以Python编写的控制台类型的应用程序,用于触发远程连接,实际连接永远不会被触发。Python扭曲连接永不触发

这里是应用程序的削减版本:

import sys 
import time 
from twisted.internet import reactor, threads, protocol 
from twisted.internet.endpoints import TCP4ClientEndpoint 
from twisted.protocols.basic import LineReceiver 

host = 'localhost' 
port = 8080 

class InterfaceFactory(protocol.Factory): 
    def buildProtocol(self, addr): 
     return protocol() 

def ConnectToMaster(): 
    deferItem = endpoint.connect(factory) 
    deferItem.addErrback(ConnectFailed) 
    print('Connecting to master') 

def MainProcessLoop(): 
    done = False 

    while True: 
     if done == False: 
      print 'Triggered connect' 
      reactor.callLater(0.1, ConnectToMaster) 
      done = True 
     time.sleep(1) 

def ConnectFailed(self, reason): 
    print('Failed to connect... : reason of {0}'.format(reason)) 

endpoint = TCP4ClientEndpoint(reactor, host, port) 
protocol = LineReceiver() 
factory = InterfaceFactory() 

reactor.callFromThread(MainProcessLoop) 
reactor.run() 

输出是:

$ python testCode.py 
Triggered connect 

我真的很困惑,这应该被扭曲101,...... MainProcessLoop处于线程,但是它是一个由Twisted管理的线程,加上reactor.run()不是任何形式的线程。

MainProcessLoop是否处于循环状态并可以阻止?实际上,在那里有一个get_input(),但是为了代码片段而将其切掉。

回答

0

的MainProcessLoop是在一个线程

至于你的例子来讲,MainProcessLoop没有任何线索。 reactor.callFromThread不产生任何线程,它假定你从一个线程执行,并且你想在反应器线程中运行某些东西。

MainProcessLoop是否在循环中并且可以阻塞?

是的,它很重要,因为MainProcessLoop实际上不在线程中。这也是你没有连接任何东西的原因。功能块和Twisted反应堆从来没有机会运行任务。

希望能回答这些问题。现在解决方案,它应该只是2个小小的变化。首先将reactor.callFromThread(MainProcessLoop)更改为reactor.callInThread(MainProcessLoop)这将产生一个线程并运行该函数。

下一页变化reactor.callLater(0.1, ConnectToMaster)

reactor.callFromThread(reactor.callLater, 0.1, ConnectToMaster) 

至于在您的示例while循环,我还是不知道你想做什么,但不管它是你应该考虑使用Twisted的事件循环,即使while循环在一个线程中。

+0

为什么要将reactor.callLater(0.1,ConnectToMaster)更改为reactor.callFromThread(reactor.callLater,0.1,ConnectToMaster)? –

+0

因为你试图在一个线程中执行'reactor'依赖的东西,'reactor'不是线程安全的。 'callFromThread'将在“main”线程中运行函数,在你希望连接到服务器的情况下,这是你想要的。 –