Home > Article > Backend Development > Share multiple methods of synchronizing multi-threads
This article mainly introduces four ways to achieve synchronization in Python multi-threading. The editor thinks it is quite good. Now I will share it with you and give it as a reference. Let’s follow the editor to take a look.
Critical resources are those resources that can only be accessed by one thread at a time. A typical example is the printer, which can only be used by one program at a time to perform the printing function, because it cannot be used by more than one thread at a time. Threads operate simultaneously, and the code that accesses this part of the resource is usually called a critical section.
Lock mechanism
Threading's Lock class, use the acquire function of this class to lock, and the realease function to unlock
import threading import time class Num: def init(self): self.num = 0 self.lock = threading.Lock() def add(self): self.lock.acquire()#加锁,锁住相应的资源 self.num += 1 num = self.num self.lock.release()#解锁,离开该资源 return num n = Num() class jdThread(threading.Thread): def init(self,item): threading.Thread.init(self) self.item = item def run(self): time.sleep(2) value = n.add()#将num加1,并输出原来的数据和+1之后的数据 print(self.item,value) for item in range(5): t = jdThread(item) t.start() t.join()#使线程一个一个执行
When a thread calls the acquire() method of the lock to acquire the lock, the lock enters the "locked" state. Only one thread can obtain the lock at a time. If another thread attempts to obtain the lock at this time, the thread will become "blocked", which is called "synchronous blocking" (see the Basic concepts of multithreading).
Until the thread that owns the lock calls the release() method of the lock to release the lock, the lock enters the "unlocked" state. The thread scheduler selects one of the threads in the synchronous blocking state to obtain the lock and makes the thread enter the running state.
Semaphore
The semaphore also provides acquire method and release method. Whenever the acquire method is called, if the internal counter is greater than 0, it is decremented by 1. If the internal counter is equal to 0, the thread will be blocked until a thread calls the release method to update the internal counter to a position greater than 1.
import threading import time class Num: def init(self): self.num = 0 self.sem = threading.Semaphore(value = 3) #允许最多三个线程同时访问资源 def add(self): self.sem.acquire()#内部计数器减1 self.num += 1 num = self.num self.sem.release()#内部计数器加1 return num n = Num() class jdThread(threading.Thread): def init(self,item): threading.Thread.init(self) self.item = item def run(self): time.sleep(2) value = n.add() print(self.item,value) for item in range(100): t = jdThread(item) t.start() t.join()The so-called conditionIt uses the Condition class to complete. Since it can also be used like a lock mechanism, it also has acquire and release methods, and it also has wait, notify, and notifyAll methods.
""" 一个简单的生产消费者模型,通过条件变量的控制产品数量的增减,调用一次生产者产品就是+1,调用一次消费者产品就会-1. """ """ 使用 Condition 类来完成,由于它也可以像锁机制那样用,所以它也有 acquire 方法和 release 方法,而且它还有 wait, notify, notifyAll 方法。 """ import threading import queue,time,random class Goods:#产品类 def init(self): self.count = 0 def add(self,num = 1): self.count += num def sub(self): if self.count>=0: self.count -= 1 def empty(self): return self.count <= 0 class Producer(threading.Thread):#生产者类 def init(self,condition,goods,sleeptime = 1):#sleeptime=1 threading.Thread.init(self) self.cond = condition self.goods = goods self.sleeptime = sleeptime def run(self): cond = self.cond goods = self.goods while True: cond.acquire()#锁住资源 goods.add() print("产品数量:",goods.count,"生产者线程") cond.notifyAll()#唤醒所有等待的线程--》其实就是唤醒消费者进程 cond.release()#解锁资源 time.sleep(self.sleeptime) class Consumer(threading.Thread):#消费者类 def init(self,condition,goods,sleeptime = 2):#sleeptime=2 threading.Thread.init(self) self.cond = condition self.goods = goods self.sleeptime = sleeptime def run(self): cond = self.cond goods = self.goods while True: time.sleep(self.sleeptime) cond.acquire()#锁住资源 while goods.empty():#如无产品则让线程等待 cond.wait() goods.sub() print("产品数量:",goods.count,"消费者线程") cond.release()#解锁资源 g = Goods() c = threading.Condition() pro = Producer(c,g) pro.start() con = Consumer(c,g) con.start()put method and task_done method, queue has a number of unfinished tasks num, put in sequence num+1, task in sequence num-1. The task ends when all tasks are completed.
import threading import queue import time import random ''' 1.创建一个 Queue.Queue() 的实例,然后使用数据对它进行填充。 2.将经过填充数据的实例传递给线程类,后者是通过继承 threading.Thread 的方式创建的。 3.每次从队列中取出一个项目,并使用该线程中的数据和 run 方法以执行相应的工作。 4.在完成这项工作之后,使用 queue.task_done() 函数向任务已经完成的队列发送一个信号。 5.对队列执行 join 操作,实际上意味着等到队列为空,再退出主程序。 ''' class jdThread(threading.Thread): def init(self,index,queue): threading.Thread.init(self) self.index = index self.queue = queue def run(self): while True: time.sleep(1) item = self.queue.get() if item is None: break print("序号:",self.index,"任务",item,"完成") self.queue.task_done()#task_done方法使得未完成的任务数量-1 q = queue.Queue(0) ''' 初始化函数接受一个数字来作为该队列的容量,如果传递的是 一个小于等于0的数,那么默认会认为该队列的容量是无限的. ''' for i in range(2): jdThread(i,q).start()#两个线程同时完成任务 for i in range(10): q.put(i)#put方法使得未完成的任务数量+1【Related recommendations】1. 2. 3.
Marco Education Python Basic Grammar Full Explanation Video
The above is the detailed content of Share multiple methods of synchronizing multi-threads. For more information, please follow other related articles on the PHP Chinese website!