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

前言:

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

调用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 锁只是需要在共享变量的地方改变就可以了。如果在整个逻辑里面使用锁的花,那就没有多线程的意义了。 


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


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

5 Responses

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

    真是经验呀

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

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

发表评论

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

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">