2017-10-05 93 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」線程中運行函數,在你希望連接到服務器的情況下,這是你想要的。 –