0

我有一个Python编程的问题。我在写一个有线程的代码。此线程是被阻止的线程。被阻塞的线程意味着:线程正在等待事件。如果事件未设置,则此线程必须等待,直到事件被设置。我期望block线程必须等待事件,而不需要等待超时!
开始阻塞的线程后,我写了一个永久循环来计算一个计数器。问题是:当我想通过Ctrl + C终止我的Python程序时,我无法正确终止阻塞的线程。这个线程还活着!我的代码在这里。Python阻塞的线程终止方法?

import threading 
import time 

def wait_for_event(e): 
    while True: 
     """Wait for the event to be set before doing anything""" 
     e.wait() 
     e.clear() 
     print "In wait_for_event" 

e = threading.Event() 
t1 = threading.Thread(name='block', 
         target=wait_for_event, 
         args=(e,)) 
t1.start() 

# Check t1 thread is alive or not 
print "Before while True. t1 is alive: %s" % t1.is_alive() 

counter = 0 
while True: 
    try: 
     time.sleep(1) 
     counter = counter + 1 
     print "counter: %d " % counter 
    except KeyboardInterrupt: 
     print "In KeyboardInterrupt branch" 
     break 

print "Out of while True" 
# Check t1 thread is alive 
print "After while True. t1 is alive: %s" % t1.is_alive() 

输出:

$ python thread_test1.py 
Before while True. t1 is alive: True 
counter: 1 
counter: 2 
counter: 3 
^CIn KeyboardInterrupt branch 
Out of while True 
After while True. t1 is alive: True 

谁能给我帮助吗?我想问2个问题。
1.我可以通过Ctrl + C停止阻塞的线程吗?如果可以的话,请给我一个可行的方向。
2.如果我们通过Ctrl + \键盘停止Python程序或重置运行Python程序的硬件(例如PC),被阻塞的线程可以被终止或不被终止?

回答

1

按Ctrl + C停止仅主线程,你的线程不在daemon模式,这就是为什么他们保持运行,这就是保持过程活着。首先让你的线程进入守护进程。

t1 = threading.Thread(name='block', 
         target=wait_for_event, 
         args=(e,)) 
t1.daemon = True 
t1.start() 

类似地为您的其他线程。但是还有另外一个问题 - 一旦主线程启动了你的线程,就没有别的办法了。所以它退出,线程立即被破坏。所以,让我们保持主线程活着:

import time 
while True: 
    time.sleep(1) 

this看看,我希望你能得到你的答案。

+0

我能问你2个问题吗?我没有线程终止的经验。我会在这里问第一个问题,因为这仍然让我不清楚。在第一个问题中,我暂时忽略了“让主线保持活跃”的情况。如果我们将t1线程设置为'daemon',那么当我们按下Ctrl + C时它还是活着吗?我把t1线程作为'daemon',但我仍然看到'After while True。当我按Ctrl + C时,t1是活着的:True'。这意味着即使主程序可以退出,但t1线程仍在运行!它是否正确? – jackbk

+0

是的,它是正确的...通过将它们设置为守护进程线程,您可以让它们运行并忘记它们,并且当程序退出时,任何守护进程线程都会自动终止。 –

+0

谢谢。我了解你对守护线程的解释。我的第二个问题是你对主线程的评论:“一旦主线程启动你的线程,就没有其他任何事情要做”,“那么让我们保持主线程活着”。你的意思是我不应该有'KeyboardInterrupt'异常?我为'KeyboardInterrupt'使用异常,因为如果用户按下Ctrl + C,我的python程序必须退出。这是我的意图。 – jackbk

1

如果你需要杀死所有正在运行的python进程,你可以简单地从命令行运行pkill python。 这是有点极端,但会工作。

另一个解决办法是使用你的代码中看到锁定here

+0

谢谢。我认为我们不应该按Ctrl + C或Ctrl + \来杀死一个程序。停止python程序并不是一个好方法。但是我真的好奇线程运行,如果我们通过Ctrl + C或Ctrl + \杀死python程序。所以我在这个主题中问了这个问题。关于“锁定”,我已阅读到目前为止,但我不熟悉这种方法。我熟悉SystemC中的“事件等待”,所以我在Python中尝试了相同的方法(事件等待)。这是在我的例子中通过“事件等待”使用阻塞线程的原因。 – jackbk