写了个多线程的python脚本,结果居然死锁了。调试了一整天才找到原因,是我使用queue的错误导致的。

为了说明问题,下面是一个简化版的代码。注意,这个代码是错的,后面会说原因和解决办法。

import Queue
import threading queue = Queue.Queue() def test(q):
while True:
if q.qsize() != 0:
d = q.get()
print d
else:
break def main():
global queue
n = 100
for i in range(66):
queue.put(i) threads = []
for i in range(n)
threads.append(threading.Thread(target=test, args = (queue,))) for i in range(n):
threads[i].start()
for i in range(n):
threads[i].join()

上面这个代码是会造成死锁的。原因就在下面这一小段。

    while True:
if q.qsize() != 0:
d = q.get()

由于有多个线程同时运行此段代码,所以队列q是各个线程共享的。

如果在q只剩一个数据的时候,有3个线程都运行到if q.qsize() != 0:,那么这3个线程都会满足此条件。从而继续运行。

然后,在d = q.get()处,只有一个线程能够取到数据,此后队列为空,另外两个线程无法取得数据,从而锁死在此处。

解决方法:加锁

import Queue
import threading queue = Queue.Queue()
mutex = threading.Lock() def test(q):
global mutex
while True:
mutex.acquire()
if q.qsize() != 0:
d = q.get()
mutex.release()
print d
else:
mutex.release()
break def main():
global queue
n = 100
for i in range(66):
queue.put(i) threads = []
for i in range(n)
threads.append(threading.Thread(target=test, args = (queue,))) for i in range(n):
threads[i].start()
for i in range(n):
threads[i].join()

【python】多线程queue导致的死锁问题的更多相关文章

  1. 第十五章、Python多线程同步锁,死锁和递归锁

    目录 第十五章.Python多线程同步锁,死锁和递归锁 1. 引子: 2.同步锁 3.死锁 引子: 4.递归锁RLock 原理: 不多说,放代码 总结: 5. 大总结 第十五章.Python多线程同步 ...

  2. day11学python 多线程+queue

    多线程+queue 两种定义线程方法 1调用threading.Thread(target=目标函数,args=(目标函数的传输内容))(简洁方便) 2创建一个类继承与(threading.Threa ...

  3. python基础-12 多线程queue 线程交互event 线程锁 自定义线程池 进程 进程锁 进程池 进程交互数据资源共享

    Python中的进程与线程 学习知识,我们不但要知其然,还是知其所以然.你做到了你就比别人NB. 我们先了解一下什么是进程和线程. 进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CP ...

  4. Python中Queue模块及多线程使用

    Python的Queue模块提供一种适用于多线程编程的FIFO实现.它可用于在生产者(producer)和消费者(consumer)之间线程安全(thread-safe)地传递消息或其它数据,因此多个 ...

  5. Python:关于subprocess.stdout.read()导致程序死锁的问题

    subprocess.stdout.read()导致程序死锁的问题解决 今天有位老哥联系我说,在我的python之路系列中,解决粘包问题那一章的代码有BUG 这里当运行命令过于庞大的时候,会导致程序直 ...

  6. python多线程--优先级队列(Queue)

    Python的Queue模块中提供了同步的.线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列PriorityQueue.这些队列都实现 ...

  7. 用Queue控制python多线程并发数量

    python多线程如果不进行并发数量控制,在启动线程数量多到一定程度后,会造成线程无法启动的错误. 下面介绍用Queue控制多线程并发数量的方法(python3). # -*- coding: utf ...

  8. python多线程,event,互斥锁,死锁,递归锁,信号量

    Python多线程/event 多线程-threading python的thread模块是⽐较底层的模块, python的threading模块是对thread做了⼀些包装的, 可以更加⽅便的被使⽤ ...

  9. GIL全局解释器锁、死锁现象、python多线程的用处、进程池与线程池理论

    昨日内容回顾 僵尸进程与孤儿进程 # 僵尸进程: 所有的进程在运行结束之后并不会立刻销毁(父进程需要获取该进程的资源) # 孤儿进程: 子进程正常运行 但是产生该子进程的父进程意外死亡 # 守护进程: ...

随机推荐

  1. 盖得化工----requests/bs4---采集二级网址

    Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...

  2. P5002 专心OI - 找祖先

    P5002 专心OI - 找祖先 给定一棵有根树(\(n \leq 10000\)),\(M \leq 50000\) 次询问, 求以 \(x\) 为 \(LCA\) 的点对个数 错误日志: 看下面 ...

  3. Python基础【day02】:字符编码(一)

    本节内容 1.字符编码与转码 1.关于中文2.注释3.转码 2.表达式for 循环 3.数据类型之数字 1.数字2.布尔值3.字符串4.列表5.元祖6.字典 一.字符编码与转码 python解释器在加 ...

  4. TCP的代码

    视频已经发布,这里是所有的代码仅供参考. TCP服务器: MainWindow里面的代码: using System; using System.Collections.Generic; using ...

  5. CircleList-使用UGUI实现的圆形列表

    CircleList CircleList是一个通过UGUI实现的圆形列表,通过缩放.平移和层级的改变模拟一个3D的圆形列表. 效果 添加与旋转 间距调整 椭圆形的旋转 参数 CenterX: 椭圆圆 ...

  6. utf8_bin跟utf8_general_ci的区别

    ci是 case insensitive, 即 "大小写不敏感", a 和 A 会在字符判断中会被当做一样的; bin 是二进制, a 和 A 会别区别对待. 例如你运行: SEL ...

  7. Python - Scrapy 框架

    Scrapy 是采用Python 开发的一个快速可扩展的抓取WEB 站点内容的爬虫框架.Scrapy,Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构 ...

  8. Java EE之Form的get与post方法

    Form表单中method="post/get'的区别 Form提供了两种数据传输的方式——get和post.虽然它们都是数据的提交方式,但是在实际传输时确有很大的不同,并且可能会对数据产生 ...

  9. 通过Application传递数据

    1:通过Application传递数据 假如有一个Activity A, 跳转到 Activity B ,并需要推荐一些数据,通常的作法是Intent.putExtra() 让Intent携带,或者有 ...

  10. Android BroadcastReceiver解析

    目录   示意图 1. 定义 即 广播,是一个全局的监听器,属于Android四大组件之一 Android 广播分为两个角色:广播发送者.广播接收者 2. 作用 监听 / 接收 应用 App 发出的广 ...