Heim  >  Artikel  >  Backend-Entwicklung  >  Teilen Sie mehrere Methoden zum Synchronisieren von Multithreads

Teilen Sie mehrere Methoden zum Synchronisieren von Multithreads

Y2J
Y2JOriginal
2017-05-11 11:13:011381Durchsuche

In diesem Artikel werden hauptsächlich die vier Methoden des Python-Multithreadings zur Erzielung einer Synchronisierung vorgestellt. Der Herausgeber findet sie recht gut, daher werde ich sie jetzt mit Ihnen teilen und als Referenz verwenden. Folgen wir dem Editor und werfen wir einen Blick darauf.

Kritische Ressourcen sind solche Ressourcen, auf die jeweils nur ein Thread zugreifen kann. Ein typisches Beispiel ist der Drucker, der jeweils nur von einem Programm verwendet werden kann um die Druckfunktion auszuführen, da sie nicht von mehr als einem Thread gleichzeitig verwendet werden kann und der Code, der auf diesen Teil der Ressource zugreift, normalerweise als kritischer Abschnitt bezeichnet wird.

Sperrmechanismus

Threadings Sperrklasse, verwenden Sie die Erwerbsfunktion dieser Klasse zum Sperren und die Realease-Funktion zum Entsperren

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()#使线程一个一个执行
Wenn ein Thread die Acquire()-Methode der Sperre aufruft, um die Sperre zu erwerben, wechselt die Sperre in den Status „gesperrt“

. Es kann jeweils nur ein Thread die Sperre erhalten. Wenn zu diesem Zeitpunkt ein anderer Thread versucht, die Sperre zu erhalten, wird der Thread „blockiert“, was als „synchrones Blockieren“ bezeichnet wird (siehe Grundkonzept von Multithreading).
Bis der Thread, der die Sperre besitzt, die release()-Methode der Sperre aufruft, um die Sperre freizugeben, wechselt die Sperre in den Status „entsperrt“. Der Thread-Scheduler wählt einen der Threads im synchronen Blockierungszustand aus, um die Sperre zu erhalten, und versetzt den Thread in den laufenden Zustand.

Semaphore

Semaphore bietet auch eine Erfassungsmethode und eine Freigabemethode. Wenn die Erfassungsmethode aufgerufen wird und der interne Zähler größer als 0 ist, wird er um 1 verringert. Wenn der interne Zähler gleich 0 ist, wird der Thread blockiert, bis ein Thread die Release-Methode aufruft, um den internen Zähler

auf eine Position größer als 1 zu aktualisieren.

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()
Bedingtes Urteil

Die sogenannte bedingte Variable

bedeutet, dass dieser Mechanismus auf bestimmten Bedingungen basiert erfüllt sein. Nur dann kann der Thread auf die relevanten Daten zugreifen.

Es verwendet die Condition-Klasse zum Vervollständigen. Da es auch als Sperrmechanismus verwendet werden kann, verfügt es auch über Erfassungs- und Freigabemethoden sowie über die Methoden wait, notify und notifyAll.

Synchronisation
"""
一个简单的生产消费者模型,通过条件变量的控制产品数量的增减,调用一次生产者产品就是+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()
Warteschlange

put-Methode und task_done-Methode, die Warteschlange enthält eine Anzahl nicht erledigter Aufgaben, Nummer, wiederum Nummer + 1 , Die Aufgaben sind nacheinander num-1. Die Aufgabe endet, wenn alle Aufgaben abgeschlossen sind.

[Verwandte Empfehlungen]

import threading
import queue
import time
import random

&#39;&#39;&#39;
1.创建一个 Queue.Queue() 的实例,然后使用数据对它进行填充。
2.将经过填充数据的实例传递给线程类,后者是通过继承 threading.Thread 的方式创建的。
3.每次从队列中取出一个项目,并使用该线程中的数据和 run 方法以执行相应的工作。
4.在完成这项工作之后,使用 queue.task_done() 函数向任务已经完成的队列发送一个信号。
5.对队列执行 join 操作,实际上意味着等到队列为空,再退出主程序。
&#39;&#39;&#39;

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)
&#39;&#39;&#39;
初始化函数接受一个数字来作为该队列的容量,如果传递的是
一个小于等于0的数,那么默认会认为该队列的容量是无限的.
&#39;&#39;&#39;
for i in range(2):
  jdThread(i,q).start()#两个线程同时完成任务

for i in range(10):
  q.put(i)#put方法使得未完成的任务数量+1
1.

Python kostenloses Video-Tutorial

2. Python-Lernhandbuch

3. Marcos lehrreiches Erklärungsvideo zur Python-Grundgrammatik

Das obige ist der detaillierte Inhalt vonTeilen Sie mehrere Methoden zum Synchronisieren von Multithreads. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn