Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
preface
At ordinary times, we will inevitably encounter the following problems in the process of moving bricks: the person who moves bricks will send them to the hands of the baseman, and then move a brick. If the baseman has not finished the base, the person who moves bricks will wait for the person who finishes the base before passing the bricks and carrying out the next move.
In order to solve this problem, we found a cart, each time the brick moving person will move the brick into the cart, and then the brick laying person will go to the cart to get, so as to avoid the waiting time in the middle, improve the efficiency of moving bricks.
In fact, the cart in this example acts as a message Queue, and today we’re going to walk into the world of queues.
On the Queue
Queue is Python’s built-in, thread-safe Queue library. It supports queue synchronization by default, realizing first in, first out, last in, first out and priority queue. Queue is widely used in multi-threaded communication.
Queue practice
First in, first out (FIFO)
from queue import Queue
from threading import Thread
def BanZhuan(q) :
print('I'm moving bricks! ')
for i in range(5) :print(F 'Moving brick information: brick -{i}--> < span style = "max-width: 100%;)
# put the bricks in the queue
q.put(F '- brick{i}')
def LeiZhuan(q) :
print('I'm building bricks! ')
while True:
# fetch bricks from queue
zhuan = q.get()
# If the queue is empty, jump out of the loop
if q.empty():
break
print(F 'brick information:{zhuan}-- > wall ')
if __name__ == '__main__':
Create queue
q=Queue(10)
Start a thread to move bricks
t1 = Thread(target=BanZhuan,args=(q,)) # Note: The comma in args must be there
Start a thread to build bricks
t2 = Thread(target=LeiZhuan,args=(q,))
# Start moving bricks & laying bricks
t1.start()
t2.start()
Copy the code
As you can see, the bricks are listed in order 0-4, and the bricks are listed in order 0-4, i.e. first in, first out.
Last in first Out (LIFO)
from queue import Queue,LifoQueue
from threading import Thread
import time,random
def BanZhuan(q) :
print('I'm moving bricks! ')
for i in range(5) :print(F 'Moving brick information: brick -{i}--> < span style = "max-width: 100%;)
# put the bricks in the queue
q.put(F '- brick{i}')
def LeiZhuan(q) :
print('I'm building bricks! ')
while True:
# fetch bricks from queue
zhuan = q.get()
time.sleep(random.random())
# If the queue is empty, jump out of the loop
if q.empty():
break
print(F 'brick information:{zhuan}-- > wall ')
if __name__ == '__main__':
Create queue
q=LifoQueue(10)
Start a thread to move bricks
t1 = Thread(target=BanZhuan,args=(q,)) # Note: The comma in args must be there
Start a thread to build bricks
t2 = Thread(target=LeiZhuan,args=(q,))
# Start moving bricks & laying bricks
t1.start()
t2.start()
Copy the code
As shown above, you can see that the order of the bricks in the last in first out queue is out of order. This is because for the bricks in the queue, I see the latest brick and I go to the pile.
Problem: Bricks don’t finish before they finish
This is because we decide in our code to exit when the queue is empty. This problem occurs when bricks are laid faster than they can be moved. We just need to add a short wait to the brick code.
PriorityQueue
When put, a tuple is passed in. The first element is the priority. The smaller the number, the higher the priority.
from queue import Queue,LifoQueue,PriorityQueue
from threading import Thread
import time,random
def BanZhuan(q) :
print('I'm moving bricks! ')
for i in range(5) :print(F 'Moving brick information: brick -{i}--> < span style = "max-width: 100%;)
The priority queue is passed a tuple, the first element is the priority, the smaller the higher the priority
q.put((100-i,F '- brick{i}'))
def LeiZhuan(q) :
print('I'm building bricks! ')
while True:
# fetch bricks from queue
zhuan = q.get()
time.sleep(random.random())
print(F 'brick information:{zhuan}-- > wall ')
# If the queue is empty, jump out of the loop
if q.empty():
break
if __name__ == '__main__':
Create queue
q=PriorityQueue(10)
Start a thread to move bricks
t1 = Thread(target=BanZhuan,args=(q,)) # Note: The comma in args must be there
Start a thread to build bricks
t2 = Thread(target=LeiZhuan,args=(q,))
# Start moving bricks & laying bricks
t1.start()
t2.start()
Copy the code
As shown above, why are tiles of priority 100 stacked first? Since both threads start at the same time, the first get gets the 100 priority brick before waiting, so it is the first stack. To solve this problem, we only need to wait a short time before laying the bricks.
.def LeiZhuan(q) :
print('I'm building bricks! ')
while True:
time.sleep(0.1)
# fetch bricks from queue
zhuan = q.get()
time.sleep(0.1)
print(F 'brick information:{zhuan}-- > wall ')
# If the queue is empty, jump out of the loop
if q.empty():
break.Copy the code
That’s all for today, thank you for reading, and we’ll see you next time.