2014-05-07 79 views
1

我有一個問題,情況就像下面的代碼。目標函數(等待)處於while循環或花費了很長時間,所以我想殺死微線程。如何殺死thread1?如何在while循環中停止gevent微線程?

import gevent 
from gevent import Timeout 

def wait(): 
    while(1): 
     pass 
    print 'end' 


timer = Timeout(1).start() 
thread1 = gevent.spawn(wait) 

try: 
    thread1.join(timeout=timer) 
except Timeout: 
    print('Thread 1 timed out') 
+0

什麼不起作用? – msvalkon

+0

你可以使用gevent.killall()! –

回答

0

你在那裏做了很多不必要的工作。你可以簡單地將秒鐘關鍵字參數傳遞給join()象下面這樣:

>>> import gevent 
>>> def wait(): 
... while True: 
...  print("In loop") 
...  gevent.sleep(1) # To not fill the screen.. 
...  
>>> 
>>> g = gevent.spawn(wait) 
>>> g.join(timeout=5) 

下面將殺死這是運行wait() 5秒鐘後greenlet。你不能趕上Timeout,因爲join()會爲你捕捉它,只要超時是它除外的那個,就會無聲無息地殺死greenlet。以下是join()greenlet.py

try: 
    t = Timeout.start_new(timeout) 
    ... SNIP ... 
except Timeout as ex: 
    self.unlink(switch) 
    if ex is not t: 
     raise 

源代碼片段,您可以殺死使用kill()以及一個greenlet。我認爲這是錯誤的方法,但我會添加例子。下面將運行greenlet 5秒鐘,然後殺死它:如果「等待」微線程切換的機會

>>> g = gevent.spawn(wait) 
>>> with gevent.Timeout(5, False): 
...  g.join() 
... g.kill() 
... 
+0

對不起,我沒有這麼清楚。我的意思是像一個while循環,但你沒有機會添加gevent.sleep(1)讓這個greenlet睡覺。就像調用第三方庫函數一樣,它很久沒有響應。 – user3611389

+0

@ user3611389我不認爲如果net永遠不會執行上下文切換,則可以通過超時greenlet來解決長時間阻塞問題。 – msvalkon

0

您的代碼纔有效。如果您控制線程的代碼,則可以通過調用gevent.sleep來實現該功能。否則,如果你的線程的代碼在python的實現,並使用IO操作您可以嘗試通過猴子修補蟒蛇功能:

from gevent.monkey import patch_all 
patch_all() 

這將使你的線程時命中各種IO操作切換。

-1

我遇到同樣的問題,我不得不殺死一個greenlet線程(它有用戶編寫的代碼)。

我們不能假設用戶編寫沒有死循環的正確代碼。

最後,我使用「Signal」API來解決這個問題。

請參考https://docs.python.org/2/library/signal.html

關於GEVENT的開關和超時:下面https://groups.google.com/forum/#!topic/gevent/eBj9YQYGBbc

碼可以爲您的信息。

from gevent.monkey import patch_all;patch_all() 
import gevent 
import time 


def fucking_loop(): 
    while True: 
     pass 


def fucking_loop_with_timeout(): 
    with gevent.Timeout(10): 
     while True: 
      pass 


def fail_to_kill(): 
    deadline = time.time() + 10 

    thread = gevent.spawn(fucking_loop) 

    while deadline > time.time(): 
     # gevent.sleep will switch out of main thread 
     gevent.sleep(1) 

    # This line of code will never been executed 
    # because gevent will not switch to main thread. 
    thread.kill() 


def fail_to_kill_2(): 

    thread = gevent.spawn(fucking_loop) 

    # Will never timeout because of the same reason 
    fucking_loop_with_timeout() 

    # This line of code will never been executed 
    # because gevent will not switch to main thread. 
    thread.join(timeout=10) 
    thread.kill() 


def kill_fucking_loop_works(): 
    import signal 
    timeout = 10 

    thread = gevent.spawn(fucking_loop) 

    def kill_thread(*args, **kwargs): 
     if not thread.dead: 
      thread.kill(timeout=1) 

    signal.signal(signal.SIGALRM, kill_thread) 
    signal.alarm(int(timeout))