2016-03-03 66 views
0

龍捲風正在單線程中運行。
在一個時間點,是否只有一個功能運行?
所以我不必鎖定保護變量?
即使這些功能是異步的?需要保護龍捲風的全局變量嗎?

+1

請添加您的代碼和相關信息。請參閱提問的教程http://stackoverflow.com/help/how-to-ask – SkyWalker

回答

0

龍捲風函數不間斷運行,直到「yield」表達式(如果函數是協程)或函數返回。所以答案是否定的,你通常不需要用Tornado應用程序中的鎖來保護全局變量。

如果您只需要一個協程可以使用共享的全局變量,那麼Python的標準線程.Lock就是實現這一目標的錯誤方法。 (事實上​​,在單線程Tornado應用程序中使用threading.Lock會導致死鎖。)而是使用tornado.locks.Lock來協調協程的訪問。但這是一種先進的用例,你幾乎不用擔心。

爲背景,讀銘文著名的「硬骨頭」文章:基於回調

https://glyph.twistedmatrix.com/2014/02/unyielding.html

這是關於雙絞線,但對於異步coroutine-和應用程序一般。

+0

前兩句似乎在異步,非阻塞堆棧中相互矛盾。 – kwarunek

0

如果在IOLoop中調度使用該變量的兩個或多個函數,則需要保護全局變量。例如。而異步處理許多http請求。

您可以使用toro's Lock在龍捲風4.2+中,您可以使用tornado.locks,因爲toro已合併到Tornado中。

的情況下:

  • 有修飾test_var並調用一個從屬函數的功能,即需要更長的時間
  • 則存在清除test_var

實施例功能:

from tornado.ioloop import IOLoop 
from tornado import gen 
import time 

test_var = 'test' 

@gen.coroutine 
def sleep(): 
    yield gen.Task(IOLoop.instance().add_timeout, time.time() + 0.1) 

@gen.coroutine 
def depend_on_test_var(): 
    yield sleep() 
    print('depend_on_test %s' % test_var) 

@gen.coroutine 
def set_test_var(): 
    global test_var 
    test_var = 'set' 
    yield depend_on_test_var() 

@gen.coroutine 
def clear_test_var(): 
    global test_var 
    test_var = 'clear' 


@gen.coroutine 
def main(): 
    print('main start %s' % test_var) 
    yield [ 
     set_test_var(), 
     clear_test_var() 
    ] 

IOLoop.instance().run_sync(main) 

它一次運行一個功能。由於yield非阻塞函數(asynchttpclient,異步睡眠等)意味着做了一些其他的事情,直到它完成,ioloop需要下一個預定功能 - 這有點過於簡化了。

當然,這僅僅是例子,並且可以單獨yields改變:

@gen.coroutine 
def main(): 
    print('main start %s' % test_var) 
    yield set_test_var() 
    yield clear_test_var() 
+0

你是對的,對不起,我沒有描述我的問題。 –