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.