Python:进程在futex(0x2a5fcc0,FUTEX_WAIT_PRIVATE,0,NULL在多线程中挂起
作者:互联网
所以我有一个队列:
q = Queue.Queue()
我在里面放一些东西.
items = ["First", "Second"]
for val in items:
q.put(val)
我正在生成15个线程.
for i in range(15):
tname = 't-%s' % i
t = my_thread(some_func, q, tname)
t.start()
q.join()
my_thread类的外观如下:
class my_thread(threading.Thread):
def __init__(self, some_func, q_, name=''):
threading.Thread.__init__(self)
self.func = some_func
self.process_q = q_
self.name = name
self.prefix = name
def run(self):
stime = time.time()
logging.info('%s thread staring at : %s' % (threading.currentThread().getname(), time.ctime(stime)))
while True:
if self.process_q.empty():
break
queue_item = self.process_q.get()
self.name = self.prefix + '-' + queue_item
try:
#run the function
except Exception as e:
logging.error('Caught some error')
finally:
self.process_q.task_done()
endTime = time.time()
logging.info('%s thread finished at: %s' % (threading.currentThread().getName(), time.ctime(endTime)))
如果我看一下日志,我看到的是两个或多个线程同时访问队列,而当队列为空时,while循环不会中断.
假设t-0线程已从队列中取出“第一”项目.
但是t-2线程可能先于t-1线程获取“第二”项目,从而使队列为空…但是当t-1进行self.process_q.empty()检查时,队列就没有空的.因此,t-1线程永远不会退出/结束并挂起.
如果我对进程ID进行跟踪,则会得到以下结果:
Process 13307 attached
futex(0x2a5fcc0, FUTEX_WAIT_PRIVATE, 0, NULL
我该如何解决???
解决方法:
您的线程随机挂在阻塞的self.process_q.get()函数中. ->种族条件
此刻,线程已启动,队列不为空.
代码部分…
...
if self.process_q.empty():
break
queue_item = self.process_q.get()
...
未在所有线程上同步.因此可以通过if条件超过2个线程(队列大小= 2).两个线程正在从self.process_q.get()函数获取结果,而其他线程正在阻塞并等待队列中的结果.
直到所有非守护进程线程都完成后,python程序才能退出.因此它永远挂起.
考虑将线程设置为守护程序模式:
for i in range(15):
tname = 't-%s' % i
t = my_thread(some_func, q, tname)
t.setDaemon(True)
t.start()
从https://docs.python.org/2/library/threading.html#threading.Thread.daemon开始:
daemon
A boolean value indicating whether this thread is a daemon thread
(True) or not (False). This must be set before start() is called,
otherwise RuntimeError is raised. Its initial value is inherited from
the creating thread; the main thread is not a daemon thread and
therefore all threads created in the main thread default to daemon =
False.The entire Python program exits when no alive non-daemon threads are left.
通过将守护程序模式设置为true,程序将在队列为空之后退出(q.join()).
标签:multithreading,queue,futex,python 来源: https://codeday.me/bug/20191027/1947412.html