文章目录
一、什么是队列?
Queue是python标准库中的线程安全的队列(FIFO)实现,提供了一个适用于多线程编程的先进先出的数据结构,即队列,用来在生产者和消费者线程之间的信息传递。
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
二、线程为什么要使用Queue(队列)?
1、在进程中,各个进程内存空间是独立的, 彼此之间不直接通讯,只能引用了消息队列来进行通讯。
2、一个线程中,多个线程内存空间是共享的,直接就能通信,引用Queue的作用也是通信,不多此一举?
3、由于每个线程都能修改共享资源, 如果不使用互斥锁,那么得到的结果有可能不可预期,因为你的一句代码,汇编可能是多行,这样在执行其中一行时,或许另一个线程开始对变量进行操作,这样会导致结果出现偏差。
4、 而python自带一个互斥锁,和三个条件变量,来保证了线程安全。
三、线程使用Queue的好处
1、保障线程安全:队列内置有锁线程安全的数据结构,不用关心数据怎么放的,只要知道怎么用就可以,怎么插数据拿数据
2、解耦: 使程序直接实现松耦合,修改一个函数,不会有串联关系。
3、提高处理效率:FIFO = 现进先出,LIFO = 后入先出。
四、 Python四种类型的Queue
方法 | 功能 |
---|---|
Queue(maxsize=0) | 创建一个先进先出队列,maxsize是个整数,指明了队列中能存放的数据个数的上限。一旦达到上限,插入会导致阻塞,直到队列中的数据被消费掉;否则为无限队列 |
LifoQueue(maxsize=0) | 创建一个后进先出的队列,maxsize是个整数,指明了队列中能存放的数据个数的上限。一旦达到上限,插入会导致阻塞,直到队列中的数据被消费掉;否则为无限队列 |
Priority Queue(maxsize=0) | 创建一个优先级队列,级别越低,越优先。 |
deque() | 双边队列,也就是在序列的前后你都可以执行添加或删除操作。 |
五、Queue对象的一些方法
方法 | 功能 |
---|---|
Queue.qsize() | 返回队列大小 |
Queue.empty() | 如果队列为空,返回True,反之False |
Queue.full() | 如果队列满了,返回True,反之False |
Queue.put(item,block=True,timeout=None) | 将item放如队列 |
Queue.put_nowait(item) | 和put(item, False)相同 |
Queue.get(block=True,timeout=None) | 从队列中取得元素 |
Queue.get_nowait() | 和get(False)相同 |
Queue.task_done() | 在完成一项工作后,向任务已经完成的队列发送一个信号 |
Queue.join() | 在队列中所有元素执行完毕并调用上面的task_done()型号之前,保持阻塞 |
q.put方法用以插入数据到队列中,put方法还有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,该方法会阻塞timeout指定的时间,直到该队列有剩余的空间。如果超时,会抛出Queue.Full异常。如果blocked为False,但该Queue已满,会立即抛出Queue.Full异常。
q.get方法可以从队列读取并且删除一个元素。同样,get方法有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,那么在等待时间内没有取到任何元素,会抛出Queue.Empty异常。如果blocked为False,有两种情况存在,如果Queue有一个值可用,则立即返回该值,否则,如果队列为空,则立即抛出Queue.Empty异常.
q.get_nowait():同q.get(False)
q.put_nowait():同q.put(False)
q.empty():调用此方法时q为空则返回True,该结果不可靠,比如在返回True的过程中,如果队列中又加入了项目。
q