Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Multithreading dalam python (ringkasan)

Multithreading dalam python (ringkasan)

WBOY
WBOYke hadapan
2022-11-16 16:56:3214306semak imbas

Artikel ini membawa anda pengetahuan yang berkaitan tentang Python, yang terutamanya memperkenalkan kandungan yang berkaitan tentang berbilang benang boleh dijalankan dalam program yang sama, dan setiap utas selesai Mari kita lihat tugasan yang berbeza di bawah ini saya harap ia dapat membantu semua.

Multithreading dalam python (ringkasan)

[Cadangan berkaitan: Tutorial video Python3]

python multi-threading

1. Konsep benang

Benang ialah unit asas untuk CPU memperuntukkan sumber. Apabila atur cara mula berjalan, atur cara menjadi satu proses dan proses adalah bersamaan dengan satu atau lebih benang. Apabila tiada pengaturcaraan berbilang benang, proses adalah bersamaan dengan utas utama apabila terdapat pengaturcaraan berbilang benang, proses mengandungi berbilang utas (termasuk utas utama). Pembangunan program yang besar boleh dicapai menggunakan benang.

Berbilang utas boleh dijalankan dalam program yang sama, dan setiap utas menyelesaikan tugasan yang berbeza.

Program perkhidmatan latar belakang berbilang benang boleh mengendalikan berbilang tugas pada masa yang sama tanpa menyekat.

Ciri pengaturcaraan berbilang benang ialah ia boleh meningkatkan kecekapan pelaksanaan program dan kelajuan pemprosesan. Program Python boleh menjalankan berbilang benang yang agak bebas secara selari pada masa yang sama.

2. Cipta berbilang benang

Python menyokong dua cara untuk mencipta berbilang benang:

~Dicipta melalui benang.Benang ().

~Dengan mewarisi threading.Kelas benang.

1 Cipta

melalui threading.Benang () Borang tatabahasa:

thread.Thread(group=Nore,targt=None,args=(),kwargs={},*,daemon=None)

Penjelasan parameter:

~kumpulan: mestilah Tiada, berkaitan dengan kelas ThreadGroup, biasanya tidak digunakan.

~sasaran: Objek yang dipanggil oleh benang ialah fungsi sasaran.

~nama: Berikan nama ini pada urutan. Lalai ialah Tread-x, x ialah nombor siri, bermula dari 1, dan nama thread pertama yang dicipta ialah Tread-1.

~args: Lulus hujah kata kunci dan kamus untuk fungsi sasaran.

~daemon: Digunakan untuk menetapkan sama ada benang keluar apabila benang utama keluar.

Contoh:

import threading
def test (x,y):
 for i in range(x,y):
   print(i)
thread1 = threading.Thread(name='t1',target= test,args=(1,10))
thread2 = threading.Thread(name='t2',target= test,args=(11,20))
thread1.start()   #启动线程1
thread2.start()   #启动线程2

Output:

1
2
3
4
5
6
7
8
9
11
12
13
14
15
16
17
18
19

Penjelasan: Kedua-dua program akan berjalan serentak, jadi hasilnya mungkin tidak berurutan 1~10 setiap kali , yang ditentukan berdasarkan segmen masa yang diperuntukkan oleh CPU kepada dua utas. Anda boleh melihat bahawa hasilnya berbeza setiap kali.

2. Mewarisi benang.Kelas benang

benang. Benang ialah kelas dan boleh diwarisi daripadanya.

Contoh:

import threading
class mythread(threading.Thread):
  def run(self):
    for i in range(1,10):
      print(i)
thread1 = mythread();
thread2 = mythread();
thread1.start()
thread2.start()

Output:

1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9

Penjelasan: Sesuaikan kelas untuk mewarisi threading.Thread, dan kemudian tulis semula kaedah larian kelas induk ke mulakan benang Kaedah ini akan dilaksanakan secara automatik apabila start() dilaksanakan.

3. Benang utama

Dalam ular sawa, utas utama ialah utas pertama untuk dimulakan.

~Benang induk: Jika benang B dimulakan dalam benang permulaan A, A ialah benang induk B.

~Sub-benang: B ialah sub-benang A.

Terdapat atribut damon semasa membuat utas, gunakannya untuk menentukan utas utama. Apabila daemon ditetapkan kepada False, utas tidak akan keluar apabila utas utama keluar, dan utas utama akan menunggu sehingga utas anak selesai melaksanakan;. Apabila daemon ditetapkan kepada Benar, utas akan keluar apabila utas utama keluar, dan utas anak lain akan dipaksa untuk keluar apabila utas utama tamat.

Perhatikan apabila menggunakan daemon:

~Atribut daemon mesti ditetapkan sebelum start(), jika tidak pengecualian RuntimeError akan dinaikkan

~Setiap utas mempunyai atribut daemon yang boleh ditetapkan secara eksplisit Anda juga tidak boleh menetapkannya Jika tidak ditetapkan, nilai lalainya ialah Tiada

~ Jika sub-sub-benang tidak menetapkan atribut daemon, ambil daemon benang semasa untuk ditetapkan. ia. Benang kanak-kanak mewarisi nilai daemon benang anak, yang mempunyai kesan yang sama seperti menetapkan Tiada.

~Semua utas yang dibuat daripada utas utama tidak menetapkan atribut daemon, dan lalainya ialah daemon=False.

Contoh:

import time
import threading
def test():
 time.sleep(10)
 for i in range(10):
  print(i)
thread1 = threading.Thread(target=test,daemon=False)
thread1.start()
print('主线程完成了')

Output:

主线程完成了
0
1
2
3
4
5
6
7
8
9

Penjelasan: Apabila utas utama selesai berjalan dan keluar, tunggu sebentar dan kemudian keluarkan 0~9. Jika daemon=False ditukar kepada daemon=True, pernyataan untuk i dalam julat(10) tidak akan dijalankan.

4. Menyekat benang

Apabila benang memanggil kaedah gabungan urutan lain, pemanggil disekat sehingga urutan panggilan ditamatkan.

Borang tatabahasa:

join(timeout-=None)

Parameter tamat masa menentukan berapa lama pemanggil menunggu Jika ia tidak ditetapkan, ia akan menunggu sehingga urutan yang dipanggil tamat. Antaranya, benang boleh dipanggil beberapa kali dengan bergabung.

Contoh:

import time
import threading
def test():
 time.sleep(5)
 for i in range(10):
  print(i)
thread1=threading.Thread(target=test)
thread1.start()
thread1.join()
print('主线程完成了')

Output:

0
1
2
3
4
5
6
7
8
9
主线程完成了

Penjelasan: Tambah thread1.join() selepas thread1.start() untuk menambah kaedah cantuman , Benang utama akan menunggu 0~9 untuk dikeluarkan sebelum melaksanakan output cetakannya sendiri.

5 Tentukan sama ada utas aktif

~run(): Kaedah yang digunakan untuk menunjukkan aktiviti utas

~start(): Mulakan thread

~join(): Tunggu sehingga thread tamat

~isAlive(): Kembalikan sama ada thread aktif

~getName(): Kembalikan nama thread

~setName(): Tetapkan nama thread

Contoh:

from threading import Thread, Event
import time
def countdown(n, started_evt):
    print('正在运行')
    started_evt.set()
    while n > 0:
        print('时间', n)
        n -= 1
        time.sleep(2)
started_evt = Event()
print('开始倒计时')
t = Thread(target=countdown, args=(10, started_evt))
t.start()
started_evt.wait()
print('倒计时运行')

Output:

开始倒计时
正在运行
时间 10
倒计时运行
时间 9
时间 8
时间 7
时间 6
时间 5
时间 4
时间 3
时间 2
时间 1

Alive,顾名思义,它表示线程当前是否为可用状态,如果线程已经启动,并且当前没有任何异常的话,则返回true,否则为false

Thread.isAlive() :顾名思义,是表示当前线程时候为可用状态,即是否已经在启动,并且在运行的状态;

六、线程同步

1.同步概念

异步模式的情况下,同时有一个线程在修改共享数据,另一个线程在读取共享数据,当修改的共享数据的线程没有处理完毕,读取数据的线程肯定会得到错误的结果。如果采用多线程的同步控制机制,当处理共享数据的线程完成处理数据之后,读取线程就读取数据。

python的锁就解决这一问题,锁住线程,只允许一个线程操作,其他线程排队等待,待当前线程操作完毕后,再按顺序一个一个来运行。

2. python的锁

python的threading模块提供了RLock锁解决方法。在某一时间只能让一个线程操作的语句放到RLock的acquire方法和release方法之间,即acquire相当于给RLack上锁,而release相当于解锁。

示例:

import threading
class mythread(threading.Thread):
 def run(self):
  global x                   #声明一个全局变量
  lock.acquire()             #上锁
  x +=10
  print('%s:%d'%(self.name,x))
  lock.release()             #解锁
x = 0                        #设置全局变量初始值
lock = threading.RLock()     #创建可重入锁
list1 = []                   
for i in range(5):   
 list1.append(mythread())    #创建五个线程,放到同一列表中
for i in list1:
 i.start()                   #开启列表线程

输出:

Thread-1:10
Thread-2:20
Thread-3:30
Thread-4:40
Thread-5:50

解释:

3. python中的条件锁

条件锁常用的方法:

~acquire([timeout]):调用关联锁的方法

~release():解锁

~wait():使线程进入 Condition 的等待池等待通知并释放解锁。使用前线程必须已获得锁定,否则将抛出异常。

~notify():从等待池挑选一个线程并通知,收到通知的线程将自动调用 acquire() 尝试获得,其他线程仍然在等待池中等待通知,直到该线程收到通知 调用该方法,否则将会抛出异常。

~notify ALL():跟notify() 一样,但这个方法对应的是所有的线程。

示例:

题目:有几个生产车间生产,几个消费者购买,当生产达到一定数量时,停止生产。

import threading
import time
condtion = threading.Condition()
sheep = ['1件产品','1件产品','1件产品','1件产品','1件产品']
class Producer(threading.Thread):
    def __init__(self, name):
        super().__init__(name=name)
        pass
    def run(self):
        global condtion, sheep
        while True:
            time.sleep(0.1)
            condtion.acquire()
            if len(sheep) < 10:
                print(self.name + "生产了1件产品")
                sheep.append(&#39;1件产品&#39;)
                condtion.notifyAll()
                pass
            else:
                print("仓库满了,停止生产!")
                condtion.wait()
                pass
            condtion.release()
        pass
    pass
class Customer(threading.Thread):
    def __init__(self, name):
        super().__init__(name=name)
        pass
    def run(self):
        global condtion, sheep
        while True:
            time.sleep(0.1)
            condtion.acquire()
            if len(sheep) > 0:
                meat = sheep.pop()
                print(self.name + "购买了" + meat + "还剩多少" + str(len(sheep)) + "件")
                condtion.notifyAll()
                pass
            else:
                print("买光了,等待")
                condtion.wait()
                pass
            condtion.release()
        pass
    pass
if __name__ == "__main__":
    p1 = Producer("1号生产车间")
    p2 = Producer("2号生产车间")
    p3 = Producer("3号生产车间")
    p4 = Producer("4号生产车间")
    p5 = Producer("5号生产车间")
    p6 = Producer("6号生产车间")
    p1.start()
    p2.start()
    p4.start()
    p5.start()
    p6.start()
    c1 = Customer('小王')
    c2 = Customer('小李')
    c3 = Customer('小贾')
    c4 = Customer('小沈')
    c5 = Customer('小刘')
    c1.start()
    c2.start()
    c3.start()
    c4.start()
    c5.start()

【相关推荐:Python3视频教程

Atas ialah kandungan terperinci Multithreading dalam python (ringkasan). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:csdn.net. Jika ada pelanggaran, sila hubungi admin@php.cn Padam