所以我有一个队列:
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)))
如果我查看日志,我看到的是两个或多个线程同时访问Queue,而当队列为空时,while循环不会中断。
假设t-0
线程已从队列中取出"first"
项。
但是t-2
线程可能会在"second"
线程可以接受它之前使用t-1
项,从而使队列为空...但是当t-1
执行self.process_q.empty()
检查时,队列不是空的。所以t-1
线程永远不会退出/结束,而是悬空。
如果我对进程ID进行了分析,我会得到以下内容:
Process 13307 attached
futex(0x2a5fcc0, FUTEX_WAIT_PRIVATE, 0, NULL
我该如何解决这个问题?
答案 0 :(得分:5)
你的线程随机挂在阻塞的self.process_q.get()函数中。 - >的竞争危害强>
目前,线程已启动,队列不为空。 代码部分......
...
if self.process_q.empty():
break
queue_item = self.process_q.get()
...
未在所有线程上同步。因此,可能有超过2个线程(队列大小= 2)通过if条件。两个线程从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:
<强>守护程序强>
一个布尔值,指示此线程是否是守护程序线程 (真)与否(假)。这必须在调用start()之前设置, 否则引发RuntimeError。它的初始值是继承自的 创建线程;主线程不是守护程序线程 因此,在主线程中创建的所有线程都默认为daemon = 假
当没有活着的非守护程序线程时,整个Python程序退出。
通过将守护程序模式设置为 true ,程序在队列为空(q.join())后退出。
答案 1 :(得分:-1)
我遇到了同样的问题,并确定在RHEL7计算机上有一个“ python / usr / bin / goferd ”进程消耗了100%的CPU。
[root @ RHELLINUXPROD〜]#ps aux | grep -i 1268 根1268 90.4 0.0 1030428 25304 Ssl Jun 04 111901:11 python / usr / bin / goferd --foreground
问题识别: 此“ / usr / bin / goferd”过程将与客户端计算机上的RedHat卫星订阅相关。
这是RedHat卫星订阅代理“ katello-ca-consumer-latest.noarch.rpm”的错误
解决方案:
临时解决方案:
在您的RHEL7计算机上找到已安装的katello代理。
[root @ RHELLINUXPROD〜]#katello-ca-consumer-rhsat-i01.0-1.noarch katello-agent-1.5.3-7.el7sat.noarch
在客户端RHEL7计算机上清理并取消注册Redhat订阅
*#个订阅管理器干净
从RHEL7客户端中删除已安装的katello代理
[root @ RHELLINUXPROD〜]#rpm -e katello-ca-consumer-rhsat-i01.0-1.noarch [root @ RHELLINUXPROD〜]#rpm -e katello-agent-1.5.3-7.el7sat.noarch
现在您可以看到使用“ ps -ef | grep -i goferd”命令输出的python进程已停止并且服务器CPU利用率恢复正常。
再次重新安装katello aganet并将服务器订阅到redhat卫星。
永久解决方案:
您必须将卫星升级到最新版本,然后才能永久解决此问题。
感谢与问候 纳马西瓦姆