Mutex lock for python multi-process

Mutex lock for python multi-process

Now three people use one printer to print content
at the same time . Three processes simulate these three people at the same time, and the output platform simulates a printer.

Let's first write an ordinary multi-process to take a look

from multiprocessing import Process
import time
import os
import random

def task1():
    print(f"{os.getpid()}开始打印了")
    time.sleep(random.randint(1,3))
    print(f"{os.getpid()}打印结束了")

def task2():
    print(f"{os.getpid()}开始打印了")
    time.sleep(random.randint(1,3))
    print(f"{os.getpid()}打印结束了")

def task3():
    print(f"{os.getpid()}开始打印了")
    time.sleep(random.randint(1,3))
    print(f"{os.getpid()}打印结束了")

if __name__ == "__main__":

    p1 = Process(target=task1)
    p2 = Process(target=task2)
    p3 = Process(target=task3)

    p1.start()
    p2.start()
    p3.start()

7976开始打印了
14068开始打印了
1240开始打印了
1240打印结束了
7976打印结束了
14068打印结束了

It seems that there is no problem, but-in real life, printers generally can only print one document at a time, and cannot print three copies together (and then randomly print out one of the three copies)

Some people say that you can use join to restrict p1, p2, and p3. It is indeed possible, but is it necessary to follow the principle of first-come, first-served? You don't know whether it is p1 or p2 or p3 to print first. If you let p1 join, what should you do if p2 comes to print first?

So here, we use a mutex-whoever comes first will print first:

from multiprocessing import Process
from multiprocessing import Lock
import time
import os
import random


def task1(p, lock):
    '''一把锁不能同时上两次,互斥锁只能上一次解一次'''
    lock.acquire()
    # lock.acquire()
    print(f"{p}开始打印了")
    time.sleep(random.randint(1, 3))
    print(f"{p}打印结束了")
    lock.release()


def task2(p, lock):
    lock.acquire()
    print(f"{p}开始打印了")
    time.sleep(random.randint(1, 3))
    print(f"{p}打印结束了")
    lock.release()


def task3(p, lock):
    lock.acquire()
    print(f"{p}开始打印了")
    time.sleep(random.randint(1, 3))
    print(f"{p}打印结束了")
    lock.release()


if __name__ == "__main__":

    mutex = Lock()

    p1 = Process(target=task1, args=('p1', mutex))
    p2 = Process(target=task2, args=('p2', mutex))
    p3 = Process(target=task3, args=('p3', mutex))

    p1.start()
    p2.start()
    p3.start()


p1开始打印了
p1打印结束了
p2开始打印了
p2打印结束了
p3开始打印了
p3打印结束了

Three tasks seize a lock at the same time, first-come, first-served. For example, task2 first seizes the lock and then executes the following program. At this time, task1 and task3 will also seize the lock. But after grabbing it, it was discovered that it was locked, and it could only be blocked and waited.

Note: In task2, when time.sleep() is blocked, the operating system forces the CPU to switch to other tasks. Other tasks find that the lock has not been opened and will continue to block until task2 releases the lock. Continue to fight for this lock.

I hope this article will help you, and your support is my driving force for continuous progress!

Guess you like

Origin blog.csdn.net/m0_50481455/article/details/113844197
Recommended