[010] python practicing internal strength: the multi-threaded task queue Queue (Detailed)


First, what is the queue?

Queue python standard library is thread-safe queue (FIFO) implemented, there is provided a FIFO data structure for multi-threaded programming, i.e., the queue for the thread between producers and consumers of information transfer.

A queue is a special linear form, is special in that it only allows deletion at the front end of the table (Front), while the rear end of insertion, the table (REAR), and stack as a queue by the operating linear restriction table. Referred to as the tail end of the end, delete operation will be referred to as head-of-insertion operation. When there is no queue element, called an empty queue.

Second, why use thread Queue (queue)?

1, in the process, each process memory space is independent, not directly communicate with each other, you can only refer to a message queue to communicate.

2, a thread, multiple threads of memory space is shared, will be able to communicate directly, also cited the role of Queue communication, do not bother?

3, because each thread can modify a shared resource, if you do not use a mutex, then the results are likely unexpected, because you a code, assembly may be multiple lines, so that the implementation of one of the rows, perhaps another variable thread starts to operate, it will result in deviation of the results.

4, while the python comes with a mutex, condition variables, and three, to ensure the security thread.

Third, the benefits of threads Queue

1, to protect thread-safe: the queue data structure built thread-safe lock, how to put the data do not care, as long as you can know how to use, how to get data interpolated data

2. Decoupling: direct the program to achieve loose coupling, modifying a function, there will be no series relationship.

3, to improve the processing efficiency: FIFO = current first out, LIFO = post-first-out.

Four, Python four types of Queue

method Features
Queue(maxsize=0) Create a FIFO queue, MAXSIZE is an integer indicating the number of the upper limit can be stored in the data queue. Once you reach the upper limit, the insertion can lead to blocked until the data queue are consumed; otherwise infinite queue
LifoQueue(maxsize=0) Create a LIFO queue, MAXSIZE is an integer indicating the number of the upper limit can be stored in the data queue. Once you reach the upper limit, the insertion can lead to blocked until the data queue are consumed; otherwise infinite queue
Priority Queue(maxsize=0) Create a lower priority queue level, the more priority.
and () Bilateral queue, that is, before and after the execution sequence of you can add or delete.

Fifth, some methods Queue object

method Features
Queue.qsize() Return queue size
Queue.empty() If the queue is empty, return True, False conversely
Queue.full() If the queue is full, return True, False and vice versa
Queue.put(item,block=True,timeout=None) The queue to put the item
Queue.put_nowait(item) And put (item, False) identical
Queue.get(block=True,timeout=None) Obtain elements from the queue
Queue.get_nowait() And get (False) the same
Queue.task_done() After completing a task, send a signal to the task has been completed in the queue
Queue.join() Before performing the completion of all of the elements in the queue and call the above task_done () model, remains blocked
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.full():调用此方法时q已满则返回True,该结果不可靠,比如在返回True的过程中,如果队列中的项目被取走。
q.qsize():返回队列中目前项目的正确数量,结果也不可靠,理由同q.empty()和q.full()一样

Six, Queue queue instance

Example 6 .1 Queue

# 先进先出
# ==========================================
import queue

q=queue.Queue()
q.put('one')
q.put('two')
q.put('three')

print(q.get())
print(q.get())
print(q.get())
'''
结果(先进先出):
one
two
three
'''

6.2 LifoQueue examples

# 先进后出概念
# ==========================================
import queue

q = queue.LifoQueue()
q.put('one')
q.put('two')
q.put('three')

print(q.get())
print(q.get())
print(q.get())
'''
结果(后进先出):
three
two
one
'''

6.3 PriorityQueue examples

import queue

q = queue.PriorityQueue()
# put进入一个元组,元组的第一个元素是优先级(通常是数字,也可以是非数字之间的比较),数字越小优先级越高
q.put((20, 'a'))
q.put((10, 'b'))
q.put((30, 'c'))

print(q.get())
print(q.get())
print(q.get())
'''
结果(数字越小优先级越高,优先级高的优先出队):
(10, 'b')
(20, 'a')
(30, 'c')
'''

6.4 collections. Deque Examples

# 双边队列
# ===================================================================

import collections
dq = collections.deque(['a', 'b'])
dq.append('c')   # 增加数据到队尾
dq.appendleft('d')  # 增加数据到队首

print(dq)  # 输出队列所有数据

print(dq.pop())  # 移除队尾,并返回
print(dq.popleft())  # 移除队首,并返回

'''
结果
deque(['d', 'a', 'b', 'c'])
c
d

'''

Seven, consumers and producers models

The next example is the producers concerned - consumers, the number of goods using Queue objects, as well as stochastic production (consumption) of. Producers and consumers and independent concurrent threads of execution.

Refer to my other blog: [003] python internal strength practice: Concurrent Programming mode of producers and consumers

from threading import Thread
import queue
import time, random




# 生产者
def producer(name,food,q):
    for i in range(1, 5):
        time.sleep(2)  # 厨师每2秒做一个包子
        print('厨师【%s】:制作了 %s 个%s' % (name, i, food))
        res = '厨师【%s】制作的第【%s】%s' % (name, i, food)
        q.put(res)  # 将制作的包子装在队列里面


# 消费者
def consumer(name, q):
    while True:
        res = q.get()  # 获取队列中的值
        time.sleep(random.randint(1, 2))  # 模拟吃包子时间
        print('消费者【%s】:吃 %s\n' % (name, res))
        q.task_done()  # 发送信号


if __name__ == "__main__":
    q = queue.Queue()  # 创建一个队列

    # 生产者们:即厨师们
    p1 = Thread(target=producer, args=('金鞍少年', '包子', q))
    p2 = Thread(target=producer, args=('nancy', '牛肉面', q))

    # 消费者们:即吃货们
    c1 = Thread(target=consumer, args=('岳云鹏', q,))
    c2 = Thread(target=consumer, args=('郭德纲', q,))
    # 设置守护进程
    c1.daemon = True
    c2.daemon = True

    # 开始
    p_l = [p1, p2, c1, c2]
    for p in p_l:
        p.start()

    p1.join()
    p2.join()
    print('主')

Published 74 original articles · won praise 79 · views 10000 +

Guess you like

Origin blog.csdn.net/weixin_42444693/article/details/105343913