2017-06-17 90 views
1

我寫了一個我的問題的示例代碼。我正在生成一個隨機字符串和一個shuffle函數,它爲消息添加了一個延遲,所以它以不同的順序出現。如何(gevent)在不等待它加入的情況下產生任務

但是,計劃任務只有在末尾有joinall後纔會執行。有沒有辦法在動態調度新產卵的時候執行調度和任務。當我一直按下Enter鍵時,它會安排一項新任務,但在我達到我設定的隨機條件之前,它不會執行。但是,如果我在追加後放置join/joinall,它會阻止。這可能與gevent有關,還有其他什麼庫可以用其他異步I/O或非阻塞庫來完成,或者我必須使用多線程。

#!/usr/bin/python 
import random 
import string 
from gevent import sleep, spawn, joinall 

def random_string(): 
    digits = "".join([random.choice(string.digits) for i in xrange(8)]) 
    chars = "".join([random.choice(string.letters) for i in xrange(10)]) 
    return chars 

def delay_message(message, delay): 
    sleep(delay) 
    print("Shuffled message: {} and time: {}". format(message, delay)) 

def main(): 
    while True: 
     s = raw_input("Please continue pressing enter, messages will appear when they are ready") 
     if s == "": 
      delay = random.randint(0, 10) 
      string = random_string() 
      print("Message: {} and time: {}". format(string, delay)) 
      tasks = [] 
      tasks.append(spawn(delay_message, string, delay)) 

      if (random.randint(0,10) == 5): # random condition in breaking 
       joinall(tasks, raise_error=True) 
       break 
     else: 
      print("Exiting") 
      break 

if __name__ == "__main__": 
    main() 
+0

'raw_input'是一個* blocking *操作系統調用。 gevent是合作的,所以當主greenlet卡在'raw_input'中時*沒有其他greenlet可以運行*。這是你的實際代碼,你有問題,或者你簡化它包含'raw_input'? –

+0

@JasonMadden代替'raw_input',它會是'sock.recv()',而不是在delay_message處打印,我會'sendall()'。這仍然會造成問題嗎? – Anderson

+0

除非你很早就對系統進行了猴子修補,或者是專門導入和使用gevent的套接字類,是的,那些仍然會阻塞會導致這個問題的調用。 –

回答

0

我發現了一個解決方案:使用ThreadPool例如tasks = ThreadPool(25)分配外循環並刪除tasks=[]joinall()

此外,添加from gevent import wait然後在休息前while循環隨機條件添加wait(),從而退出程序之前,現有的任務可以完成

+0

所以如果你monkeypatch,正常的事情變成gevent屈服事件,如睡眠和io閱讀...... –

0

無論您是否加入,您都可以完成工作,您只需在需要確保工作完成之前加入以確保併發性,您可以使用大量方法獲取狀態(隊列,共享變量,回調,委託方法),因爲你使用的是greenlet,你甚至不需要像添加數字那樣鎖定原子操作,因爲它們正在發生同一個線程。

相關問題