Twisted 的 callInThread 和 callFromThread 區別
這兩個函數的定義在 IReactorThreads 的文檔里。
Method callInThread :
Run the callable object in a separate thread.
Method callFromThread :
Cause a function to be executed by the reactor thread.
Use this method when you want to run a function in the reactor's thread from another thread. Calling callFromThread should wake up the main thread (where reactor.run() is executing) and run the given callable in that thread.
If you're writing a multi-threaded application the callable may need to be thread safe, but this method doesn't require it as such. If you want to call a function in the next mainloop iteration, but you're in the same thread, use callLater with a delay of 0.
也就是說,reactor.callFromThread 是在由 reactor.run() 激發的主消息循環(main event loop)中執行,所以也就能被 reactor.stop() 終止執行。甚至可以通過:
reactor.callFromThread(reactor.stop)
來主動要求主消息循環關閉 reactor 的主線程運行。
callFromThread 有時候比較危險,如果壓的任務太多,會阻塞主消息循環,造成其他事件無法得到及時的處理。
參考 callInThread 的代碼,可以看出它是在 reactor 的一個私有線程池里工作的:
def callInThread(self, _callable, *args, **kwargs):
if self.threadpool is None:
self._initThreadPool()
self.threadpool.callInThread(_callable, *args, **kwargs)
所以,我們可以通過
from twisted.internet import reactor
reactor.suggestThreadPoolSize(15)
來設置該線程池的大小。默認最小是5個線程,最大10個(the default reactor uses a minimum size of 5 and a maximum size of 10)。
另外:
twisted里是通過回調機制來實現類似於多線程,意思是防止程序的運行由於等待某項任務的完成而陷入阻塞停滯,提高整體運行的效率。
from twisted.internet import reactor
1. reactor.callFromThread
Method callFromThread:
Cause a function to be executed by the reactor thread.
Use this method when you want to run a function in the reactor's thread from another thread. Calling callFromThread should wake up the main thread (where reactor.run() is executing) and run the given callable in that thread.
If you're writing a multi-threaded application the callable may need to be thread safe, but this method doesn't require it as such. If you want to call a function in the next mainloop iteration, but you're in the same thread, use callLater with a delay of 0.
此方法是本身是mainloop的線程,用reactor.stop()可以終止它。也可以reactor.callFromThread(reactor.stop)來終止它。但是這個方法會阻塞到主循環。
from twisted.internet import reactor
import time
def tt(i,j):
while 1 :
print i, ' --------------- ' ,j
time.sleep( 1 )
reactor.callFromThread(tt, 1 , 1 )
reactor.callFromThread(tt, 4 , 2 )
reactor.run()
上面代碼運行的結果是無限的打印1-------------------1,這個說明了主循環被阻塞住。
2. reactor.callInThread
Method callInThread:
Run the callable object in a separate thread.
此方法是創建獨立的線程,用reactor stop方法無法停止它。這里涉及到一個線程池的概念
reactor.suggestThreadPoolSize(15)來設置線程池的大小,默認是最小是5,最大是10.如果在默認情況下
3. from twisted.internet import threads
threads.deferToThread(function),和callInThread一樣,區別只是 deferToThread 可以返回一個deferred對象,從而允許你設定回調函數。

