python - BoundedSemaphore 在 KeyboardInterrupt 上挂起在线程中

标签 python multithreading

如果在尝试获取信号量时引发键盘中断,则尝试释放同一信号量对象的线程将无限期挂起。

代码:

import threading
import time

def worker(i, sema):
    time.sleep(2)
    print i, "finished"
    sema.release()


sema = threading.BoundedSemaphore(value=5)
threads = []
for x in xrange(100):
    sema.acquire()
    t = threading.Thread(target=worker, args=(x, sema))
    t.start()
    threads.append(t)

启动它,然后在运行时按 ^C。它会挂起并且永远不会退出。

0 finished
3 finished
1 finished
2 finished
4 finished
^C5 finished
Traceback (most recent call last):
  File "/tmp/proof.py", line 15, in <module>
    sema.acquire()
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/threading.py", line 290, in acquire
    self.__cond.wait()
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/threading.py", line 214, in wait
    waiter.acquire()
KeyboardInterrupt
6 finished
7 finished
8 finished
9 finished

怎样才能让它让最后几个线程自然死亡然后正常退出呢? (如果你不尝试打断它,它就会这样做)

最佳答案

您可以使用信号模块设置一个标志,告诉主线程停止处理:

import threading
import time
import signal
import sys

sigint = False

def sighandler(num, frame):
  global sigint
  sigint = True

def worker(i, sema):
  time.sleep(2)
  print i, "finished"
  sema.release()

signal.signal(signal.SIGINT, sighandler)
sema = threading.BoundedSemaphore(value=5)
threads = []
for x in xrange(100):
  sema.acquire()
  if sigint:
    sys.exit()
  t = threading.Thread(target=worker, args=(x, sema))
  t.start()
  t.join() 
  threads.append(t)

关于python - BoundedSemaphore 在 KeyboardInterrupt 上挂起在线程中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/936933/

相关文章:

python - Python 2 和 Python 3 中 zip() 函数的区别

python - 不同连续子数组的数量

VB.Net 线程

python - 将元组转换为整数

python - HTML 标签中内容的正则表达式模式

python - Python 中的 Hello World : fatal block stack overflow?

java - 同步线程对象的run()方法

c++ - 终止正在运行的 boost 线程

java - 线程被锁定

java - 使用 Executor 和 Runnable 一起在一段时间后杀死线程