![](/img/trans.png)
[英]add_callback with thread pool, but Exception about “Cannot write() after finish().”
[英]How to create multiple add_callback in tornado?
我正在嘗試在龍卷風主循環中添加多個回調。 但是當我運行這段代碼時:
def task(num):
print 'task %s' % num
if __name__ == '__main__':
for i in range(1,5):
tornado.ioloop.IOLoop.instance().add_callback(callback=lambda: task(num=i))
tornado.ioloop.IOLoop.instance().start()
我得到輸出5次:'任務5',而不是任務1 ..任務5.當我改變主要時 :
tornado.ioloop.IOLoop.instance().add_callback(callback=lambda: task(1))
tornado.ioloop.IOLoop.instance().add_callback(callback=lambda: task(2))
tornado.ioloop.IOLoop.instance().add_callback(callback=lambda: task(3))
tornado.ioloop.IOLoop.instance().add_callback(callback=lambda: task(4))
一切正常(我在輸出中得到task1-task5)。 我在第一種情況下做錯了什么?
也許在JS中有同樣的問題? 看看這個答案: 循環內部的JavaScript閉包 - 簡單實用的例子
“問題是你的每個匿名函數中的變量i都被綁定到函數之外的同一個變量。”
嘗試簡單的測試:
def task(num):
print 'task %s' % num
def create_task(num):
tornado.ioloop.IOLoop.instance().add_callback(callback=lambda: task(num))
if __name__ == '__main__':
for i in range(1,5):
create_task(i)
tornado.ioloop.IOLoop.instance().start()
將lambda包裝到functools.partial()函數中,該函數解決了“指針問題” IOLoop.instance().add_callback(callback=functools.partial(task, i*10))
TL;博士;
這是一個帶有“指針問題”BUG的例子:
def task(num):
print(num)
for i in range(1, 6):
print ("poop {0}".format(i))
IOLoop.instance().add_callback(callback=lambda: task(i))
IOLoop.instance().start()
在上面的代碼示例中, i
將是一個指向當前迭代的值range()
的內存指針。 它從1變為2然后變為3,4,5。
Tornado的add_callback()異步函數將控制權返回給主程序,使得對task()
函數的所有5次調用幾乎同時執行。 在這一點上, i
已經獲得了5
的價值。
要快速解決這個問題,請使用funtools.partial
函數代替lambda並研究差異;)
這是無BUG示例:
IOLoop.instance().add_callback(callback=functools.partial(task, i*10))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.