欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python基礎(chǔ)之并發(fā)編程(一)

 更新時(shí)間:2021年10月27日 14:54:39   作者:寵乖?xún)x  
這篇文章主要介紹了詳解python的并發(fā)編程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一、進(jìn)程(Process)

是一個(gè)具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合的一次運(yùn)行活動(dòng)

二、線(xiàn)程(Thread)

是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位。它被包含在進(jìn)程之中,是進(jìn) 程中的實(shí)際運(yùn)作單位。

三、并發(fā)編程解決方案:

1、多任務(wù)的實(shí)現(xiàn)有 3 種方式:

  • 多進(jìn)程模式;
  • 多線(xiàn)程模式;
  • 多進(jìn)程+多線(xiàn)程模式

四、多線(xiàn)程實(shí)現(xiàn) (兩種)

1、第一種 函數(shù)方法

# 方法包裝-啟動(dòng)多線(xiàn)程
from threading import Thread 
from time import sleep, time 
def func1(name): 
    print("Threading:{} start".format(name)) 
    sleep(3) 
    print("Threading:{} end".format(name)) 
if __name__ == '__main__': 
    # 開(kāi)始時(shí)間 
    start = time() 
    # 創(chuàng)建線(xiàn)程列表 
    t_list = [] 
    # 循環(huán)創(chuàng)建線(xiàn)程 
    for i in range(10): 
        t = Thread(target=func1, args=('t{}'.format(i),)) 
        t.start() 
        t_list.append(t) 
    # 等待線(xiàn)程結(jié)束 
    for t in t_list: 
        t.join() 
    # 計(jì)算使用時(shí)間 
    end = time() - start 
    print(end)

2、第二種 類(lèi)方法包裝

# 類(lèi)包裝-啟動(dòng)多線(xiàn)程 
from threading import Thread 
from time import sleep, time 
class MyThread(Thread): 
    def __init__(self,name): 
        Thread.__init__(self) 
        self.name =name 
    def run(self): 
        print("Threading:{} start".format(self.name)) 
        sleep(3) 
        print("Threading:{} end".format(self.name)) 
if __name__ == '__main__': 
    # 開(kāi)始時(shí)間 
    start = time() 
    # 創(chuàng)建線(xiàn)程列表 
    t_list = [] 
    # 循環(huán)創(chuàng)建線(xiàn)程 
    for i in range(10): 
        t = MyThread('t{}'.format(i)) 
        t.start() 
        t_list.append(t) 
    # 等待線(xiàn)程結(jié)束 
    for t in t_list: 
        t.join() 
    # 計(jì)算使用時(shí)間 
    end = time() - start 
    print(end)

注意:

主線(xiàn)程不會(huì)等待子線(xiàn)程運(yùn)行結(jié)束,如果需要等待可使用 join()方法不要啟動(dòng)線(xiàn)程后立即 join(),很容易造成串行運(yùn)行,導(dǎo)致并發(fā)失效

五、守護(hù)線(xiàn)程與子線(xiàn)程

1、線(xiàn)程在分法有:

主線(xiàn)程:程序的本身

子線(xiàn)程:在程序另開(kāi)起的線(xiàn)程

2、守護(hù)線(xiàn)程

主要的特征是它的生命周期。主線(xiàn)程死亡,它也就隨之 死亡

# 類(lèi)包裝-啟動(dòng)多線(xiàn)程 
from threading import Thread 
from time import sleep, time 
class MyThread(Thread): 
    def __init__(self,name): 
        Thread.__init__(self) 
        self.name =name 
    def run(self): 
        print("Threading:{} start".format(self.name)) 
        sleep(3) 
        print("Threading:{} end".format(self.name)) 
if __name__ == '__main__': 
    # 開(kāi)始時(shí)間 
    start = time() 
    # 循環(huán)創(chuàng)建線(xiàn)程 
    for i in range(10): 
        t = MyThread('t{}'.format(i)) 
        t.setDaemon(True)
        t.start() 
    # 計(jì)算使用時(shí)間 
    end = time() - start 
    print(end)

六、鎖

from threading import Thread 
def func1(name): 
    print('Threading:{} start'.format(name)) 
    global num 
    for i in range(50000000): # 有問(wèn)題 
    #for i in range(5000): # 無(wú)問(wèn)題 
        num += 1 
    print('Threading:{} end num={}'.format(name, num))
if __name__ == '__main__': 
    num =0 
    # 創(chuàng)建線(xiàn)程列表 
    t_list = [] 
    # 循環(huán)創(chuàng)建線(xiàn)程 
    for i in range(5): 
        t = Thread(target=func1, args=('t{}'.format(i),)) 
        t.start() 
        t_list.append(t) 
    # 等待線(xiàn)程結(jié)束 
    for t in t_list: 
        t.join()

Python 使用線(xiàn)程的時(shí)候,會(huì)定時(shí)釋放 GIL 鎖,這時(shí)會(huì) sleep,所以才會(huì)出現(xiàn)上面的問(wèn)題。 面對(duì)這個(gè)問(wèn)題,如果要解決此問(wèn)題,我們可以使用 Lock 鎖解決此問(wèn)題( 加鎖的目的是:保證數(shù)據(jù)安全)

from threading import Thread,Lock 
def func1(name):
    # 獲取鎖
    lock.acquire()
    with lock:
        global count
        for i in range(100000):
            count += 1
    # 釋放鎖 
    lock.release()
if __name__ == "__main__":
    count = 0
    t_list = []
    # 創(chuàng)建鎖對(duì)象
    lock = Lock()
    for i in range(10):
        t = Thread(target=func1,args=(f't{i+1}',))
        t.start()
        t_list.append(t)
    for t in t_list:
        t.join()
    print(count)

七、死鎖

from threading import Thread, Lock #Lock 鎖 同步鎖 互斥鎖
from time import sleep 
def fun1(): 
    lock1.acquire() 
    print('fun1 拿到鍵盤(pán)') 
    sleep(2) 
    lock2.acquire() 
    print('fun1 拿到鼠標(biāo)') 
    lock2.release() 
    print('fun1 釋放鼠標(biāo)') 
    lock1.release() 
    print('fun1 釋放鍵盤(pán)') 
def fun2(): 
    lock2.acquire() 
    print('fun2 拿到鼠標(biāo)') 
    lock1.acquire() 
    print('fun2 拿到鍵盤(pán)') 
    lock1.release() 
    print('fun2 釋放鍵盤(pán)') 
    lock2.release() 
    print('fun2 釋放鼠標(biāo)') 
if __name__ == '__main__':
    lock1 = Lock() 
    lock2 = Lock() 
    t1 = Thread(target=fun1) 
    t2 = Thread(target=fun2) 
    t1.start() 
    t2.start()
from threading import RLock
'''
Lock 鎖 同步鎖 互斥鎖
RLock 遞歸鎖
'''
def func1():
    lock.acquire()
    print('func1獲取鎖')
    func2()
    lock.release()
    print('func1釋放鎖')
def func2():
    lock.acquire()
    print('func2獲取鎖')
    lock.release()
    print('func2釋放鎖')
def func3():
    func1()
    func2()
if __name__ == "__main__":
    #lock = Lock()  會(huì)產(chǎn)生錯(cuò)誤 
    lock = RLock()
    func3()

八、信號(hào)量(Semaphore)

我們都知道在加鎖的情況下,程序就變成了串行,也就是單線(xiàn)程,而有時(shí),我們?cè)诓挥每?慮數(shù)據(jù)安全時(shí),為了避免業(yè)務(wù)開(kāi)啟過(guò)多的線(xiàn)程時(shí)。我們就可以通過(guò)信號(hào)量(Semaphore)來(lái) 設(shè)置指定個(gè)數(shù)的線(xiàn)程。(比如:電梯每次只能承載三個(gè)人,那么同時(shí)只能有三個(gè)人乘坐,其他人只能等別人做完才能乘坐)

from time import sleep
from threading import Thread
from threading import BoundedSemaphore
def index(num):
    lock.acquire()
    print(f'第{num}個(gè)人乘坐?。?)
    sleep(2)
    lock.release()
if __name__ == "__main__":
    lock = BoundedSemaphore(3)
    for i in range(10):
        t = Thread(target=index,args=(f'{i+1}',))
        t.start()

九、事件(Event)

Event()可以創(chuàng)建一個(gè)事件管理標(biāo)志,該標(biāo)志(event)默認(rèn)為 False,event 對(duì)象主要有 四種方法可以調(diào)用:

1、 event.wait(timeout=None):調(diào)用該方法的線(xiàn)程會(huì)被阻塞,如果設(shè)置了 timeout 參數(shù),超時(shí)后,線(xiàn)程會(huì)停止阻塞繼續(xù)執(zhí)行;

2、event.set():將 event 的標(biāo)志設(shè)置為 True,調(diào)用 wait 方法的所有線(xiàn)程將被喚 醒;

3、event.clear():將 event 的標(biāo)志設(shè)置為 False,調(diào)用 wait 方法的所有線(xiàn)程將被 阻塞;

4、event.is_set():判斷 event 的標(biāo)志是否為 True。

十、線(xiàn)程通信-隊(duì)列

線(xiàn)程安全是多線(xiàn)程編程時(shí)的計(jì)算機(jī)程序代碼中的一個(gè)概念。在擁有共享數(shù)據(jù)的多條線(xiàn)程并 行執(zhí)行的程序中,線(xiàn)程安全的代碼會(huì)通過(guò)同步機(jī)制保證各個(gè)線(xiàn)程都可以正常且正確的執(zhí)行,不 會(huì)出現(xiàn)數(shù)據(jù)污染等意外情況

1使用的隊(duì)列的好處:

1. 安全

2. 解耦

3. 提高效率

2Queue模塊中的常用方法:

Python的Queue模塊中提供了同步的、線(xiàn)程安全的隊(duì)列類(lèi),包括FIFO(先入先出)隊(duì)列Queue,LIFO(后入先出)隊(duì)列LifoQueue,和優(yōu)先級(jí)隊(duì)列PriorityQueue。這些隊(duì)列都實(shí)現(xiàn)了鎖原語(yǔ),能夠在多線(xiàn)程中直接使用??梢允褂藐?duì)列來(lái)實(shí)現(xiàn)線(xiàn)程間的同步

  • Queue.qsize() 返回隊(duì)列的大小
  • Queue.empty() 如果隊(duì)列為空,返回True,反之False
  • Queue.full() 如果隊(duì)列滿(mǎn)了,返回True,反之False
  • Queue.full maxsize 大小對(duì)應(yīng)
  • Queue.get([block[, timeout]])獲取隊(duì)列,timeout等待時(shí)間
  • Queue.get_nowait() 相當(dāng)Queue.get(False)
  • Queue.put(item) 寫(xiě)入隊(duì)列,timeout等待時(shí)間
  • Queue.put_nowait(item) 相當(dāng)Queue.put(item, False)
  • Queue.task_done() 在完成一項(xiàng)工作之后,Queue.task_done()函數(shù)向任務(wù)已經(jīng)完成的隊(duì)列發(fā)送一個(gè)信號(hào)
  • Queue.join() 實(shí)際上意味著等到隊(duì)列為空,再執(zhí)行別的操作

十一、生產(chǎn)者和消費(fèi)者模式

生產(chǎn)者消費(fèi)者模式是通過(guò)一個(gè)容器來(lái)解決生產(chǎn)者和消費(fèi)者的強(qiáng)耦合問(wèn)題。生產(chǎn)者和消費(fèi)者 彼此之間不直接通訊,而通過(guò)阻塞隊(duì)列來(lái)進(jìn)行通訊,所以生產(chǎn)者生產(chǎn)完數(shù)據(jù)之后不用等待消費(fèi) 者處理,直接扔給阻塞隊(duì)列,消費(fèi)者不找生產(chǎn)者要數(shù)據(jù),而是直接從阻塞隊(duì)列里取,阻塞隊(duì)列 就相當(dāng)于一個(gè)緩沖區(qū),平衡了生產(chǎn)者和消費(fèi)者的處理能力。

from threading import Thread
from queue import Queue
from time import sleep
def producer():
    num = 1
    while True:
        print(f'生產(chǎn)了{(lán)num}號(hào)皮卡丘')
        qe.put(f'{num}號(hào)皮卡丘')
        num += 1 
        sleep(1)
def consumer():
    print('購(gòu)買(mǎi)了{(lán)}'.format(qe.get()))
    sleep(2)
if __name__ == "__main__":
    # 共享數(shù)據(jù)的容器
    qe= Queue(maxsize=5)
    # 創(chuàng)建生產(chǎn)者線(xiàn)程
    t1 = Thread(target = producer)
    # 創(chuàng)建消費(fèi)者線(xiàn)程
    t2 = Thread(target = consumer)
    # 創(chuàng)建消費(fèi)者線(xiàn)程
    t3 = Thread(target = consumer)
    # 開(kāi)始工作
    t1.start()
    t2.start()
    t3.start()

總結(jié)

本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • Python for循環(huán)與getitem的關(guān)系詳解

    Python for循環(huán)與getitem的關(guān)系詳解

    這篇文章主要介紹了Python for循環(huán)與getitem的關(guān)系詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • Python功能點(diǎn)實(shí)現(xiàn):函數(shù)級(jí)/代碼塊級(jí)計(jì)時(shí)器

    Python功能點(diǎn)實(shí)現(xiàn):函數(shù)級(jí)/代碼塊級(jí)計(jì)時(shí)器

    今天小編就為大家分享一篇關(guān)于Python功能點(diǎn)實(shí)現(xiàn):函數(shù)級(jí)/代碼塊級(jí)計(jì)時(shí)器,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • 關(guān)于WARNING:Ignoring?invalid?distribution?-pencv-python....警告信息的處理方法(已解決!)

    關(guān)于WARNING:Ignoring?invalid?distribution?-pencv-python....

    這篇文章主要給大家介紹了關(guān)于WARNING:Ignoring?invalid?distribution?-pencv-python....警告信息的處理方法,文中通過(guò)圖文將解決的辦法介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-03-03
  • python對(duì)list中的每個(gè)元素進(jìn)行某種操作的方法

    python對(duì)list中的每個(gè)元素進(jìn)行某種操作的方法

    今天小編就為大家分享一篇python對(duì)list中的每個(gè)元素進(jìn)行某種操作的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • Python中Selenium對(duì)Cookie的操作方法

    Python中Selenium對(duì)Cookie的操作方法

    Cookie內(nèi)記錄用戶(hù)名和密碼(加密)信息,只要請(qǐng)求時(shí)服務(wù)器收到Cookie,識(shí)別成功,默認(rèn)為已登陸,今天通過(guò)本文給大家分享Selenium對(duì)Cookie的操作方法,感興趣的朋友一起看看吧
    2021-07-07
  • python?scrapy框架的日志文件問(wèn)題

    python?scrapy框架的日志文件問(wèn)題

    這篇文章主要介紹了python?scrapy框架的日志文件問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Python迭代器與生成器基本用法分析

    Python迭代器與生成器基本用法分析

    這篇文章主要介紹了Python迭代器與生成器基本用法,結(jié)合實(shí)例形式分析了Python迭代器與生成器的基本功能、定義及使用方法,需要的朋友可以參考下
    2018-07-07
  • pyinstaller打包后,配置文件無(wú)法正常讀取的解決

    pyinstaller打包后,配置文件無(wú)法正常讀取的解決

    這篇文章主要介紹了pyinstaller打包后,配置文件無(wú)法正常讀取的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • 一張圖帶我們?nèi)腴T(mén)Python基礎(chǔ)教程

    一張圖帶我們?nèi)腴T(mén)Python基礎(chǔ)教程

    啄木鳥(niǎo)社區(qū)上原始翻譯后繪制的,最早這個(gè)圖是出現(xiàn)在,這個(gè)圖太棒了,有編程基礎(chǔ)的人一下子就了解 Python 的用法了。真正的 30 分鐘上手,需要的朋友可以參考下
    2017-02-02
  • opencv實(shí)現(xiàn)簡(jiǎn)單人臉識(shí)別

    opencv實(shí)現(xiàn)簡(jiǎn)單人臉識(shí)別

    這篇文章主要為大家詳細(xì)介紹了opencv實(shí)現(xiàn)簡(jiǎn)單人臉識(shí)別,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08

最新評(píng)論