python多线程获取队列引起程序挂起堵塞的情况

前言:

      尼玛悲剧呀,今天被一个小问题折腾死了,场景很简单,产品经理说,大量的节点的数据都不动了,哥们一听,这个火呀。 怎么可能,哥们写的代码这么健壮。 

[ruifengyun@bj-buzz-dev01 ~]$ sudo strace -p 2583
Process 2583 attached - interrupt to quit
futex(0x1f71e10, FUTEX_WAIT_PRIVATE, 0, NULL

调用salt api批量一看,进程还都是存在的,时间片貌似也有。因为前几天 上线了个关于Hbase的batch的逻辑和数据的本地化缓存的fix,然后就开始纠结了,来来回回检查了好几遍这两个逻辑,但是实在是没啥问题。 只能是上大杀器strace了,用strace追踪pid,看到的结果是 futex, FUTEX_WAIT_PRIVATE的现象。  

嗯哼,原文地址是 blog.xiaorui.cc

      原来是 FUTEX_WAIT_PRIVATE呀,这个现象哥以前碰见过,是发生在redis 堵塞的情况,那么问题来了,我这边的逻辑没有redis的。 最后确定到是python queue的问题。 

解决的方法,queue 的 get() 是堵塞的。如果你是多线程去判断queue的大小,然后同时去取任务,如果这个时候,你的任务的数量小于线程的数目的时候,没有取到任务的线程就会被你的get()堵塞掉。 

你可以用get(timeout=2)做超时的控制,queue模块还有个get_,或者是在判断队列大小和get队列的时候,用mutex lock堵塞锁定这个逻辑。 

不管是多线程还是多进程  lock 锁只是需要在共享变量的地方改变就可以了。如果在整个逻辑里面使用锁的花,那就没有多线程的意义了。 

        if mutex.acquire(1):
            num = num+1
            msg = self.name+' set num to '+str(num)
            print msg
            mutex.release()


In [1]: import Queue

In [2]: q = Queue.Queue()

In [3]: q.get
q.get         q.get_nowait

In [3]: q.get_nowait()
---------------------------------------------------------------------------
Empty                                     Traceback (most recent call last)

---- 1 q.get_nowait()

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/Queue.pyc in get_nowait(self)
    188         raise the Empty exception.
    189         """
    190         return self.get(False)
    191
    192     # Override these methods to implement other queue organizations

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/Queue.pyc in get(self, block, timeout)
    163             if not block:
    164                 if not self._qsize():
    165                     raise Empty
    166             elif timeout is None:
    167                 while not self._qsize():

Empty:

In [4]: q.get()

堵塞中... ...

太粗心了, 好久没用多线程了, 这段时间基本在用gevent协程,gevent是可以保证数据的安全性质的。 总之,记得以后threading要记得加锁  [ mutex ]!!!


大家觉得文章对你有些作用! 如果想赏钱,可以用微信扫描下面的二维码,感谢!
另外再次标注博客原地址  xiaorui.cc

5 Responses

  1. 360ops 2014年11月29日 / 上午12:12

    真是经验呀

    • 峰云 2014年11月19日 / 下午12:28

      啥广告呀? 你说的是爬虫的那个么? 总是被爬虫爬,尼玛受不鸟了。

发表评论

邮箱地址不会被公开。 必填项已用*标注