最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python學(xué)習(xí)筆記之線程

 更新時間:2021年11月08日 17:26:28   作者:東山絮柳仔  
這篇文章主要介紹了Python線程詳解,本文詳細(xì)講解了線程方方面面的知識,如線程基礎(chǔ)知識線程狀態(tài)、線程同步(鎖)、線程通信(條件變量)等內(nèi)容,需要的朋友可以參考下

1.自定義進(jìn)程

自定義進(jìn)程類,繼承Process類,重寫run方法(重寫Process的run方法)。

from multiprocessing import Process
import time
import os
class MyProcess(Process):
    def __init__(self, name):  ##重寫,需要__init__,也添加了新的參數(shù)。        ##Process.__init__(self) 不可以省略,否則報錯:AttributeError:'XXXX'object has no attribute '_colsed'
        Process.__init__(self)
        self.name = name
    def run(self):
        print("子進(jìn)程(%s-%s)啟動" % (self.name, os.getpid()))
        time.sleep(3)
        print("子進(jìn)程(%s-%s)結(jié)束" % (self.name, os.getpid()))
if __name__ == '__main__':
    print("父進(jìn)程啟動")
    p = MyProcess("Ail")
    # 自動調(diào)用MyProcess的run()方法
    p.start()
    p.join()
    print("父進(jìn)程結(jié)束")

# 輸出結(jié)果
父進(jìn)程啟動
子進(jìn)程(Ail-38512)啟動
子進(jìn)程(Ail-38512)結(jié)束
父進(jìn)程結(jié)束

2.進(jìn)程與線程

多進(jìn)程適合在CPU密集型操作(CPU操作指令比較多,如科學(xué)計算、位數(shù)多的浮點計算);

多線程適合在IO密集型操作(讀寫數(shù)據(jù)操作比較多的,比如爬蟲、文件上傳、下載)

線程是并發(fā),進(jìn)程是并行:進(jìn)程之間互相獨立,是系統(tǒng)分配資源的最小單位,同一個進(jìn)程中的所有線程共享資源。

進(jìn)程:一個運行的程序或代碼就是一個進(jìn)程,一個沒有運行的代碼叫程序。進(jìn)程是系統(tǒng)進(jìn)行資源分配的最小單位,進(jìn)程擁有自己的內(nèi)存空間,所以,進(jìn)程間數(shù)據(jù)不共享,開銷大。

進(jìn)程是程序的一次動態(tài)執(zhí)行過程。每個進(jìn)程都擁有自己的地址空間、內(nèi)存、數(shù)據(jù)棧以及其它用于跟蹤執(zhí)行的輔助數(shù)據(jù)。操作系統(tǒng)負(fù)責(zé)其上所有進(jìn)程的執(zhí)行,操作系統(tǒng)會為這些進(jìn)程合理地分配執(zhí)行時間。

線程:調(diào)度執(zhí)行的最小單位,也叫執(zhí)行路徑,不能獨立存在,依賴進(jìn)程的存在而存在,一個進(jìn)程至少有一個線程,叫做主線程,多個線程共享內(nèi)存(數(shù)據(jù)共享和全局變量),因此提升程序的運行效率。

線程是操作系統(tǒng)能夠進(jìn)行運算調(diào)度的最小單位,它被包含在進(jìn)程之中,是進(jìn)程中的實際運作單位。一條線程指的是進(jìn)程中一個單一順序的控制流,一個進(jìn)程中可以并發(fā)多個線程,每條線程并行執(zhí)行不同的任務(wù)。一個線程是一個execution context(執(zhí)行上下文),即一個CPU執(zhí)行時所需要的一串指令。

主線程:主線程就是創(chuàng)建線程進(jìn)程中產(chǎn)生的第一個線程,也就是main函數(shù)對應(yīng)的線程。

協(xié)程:用戶態(tài)的輕量級線程,調(diào)度由用戶控制,擁有自己的寄存器上下文和棧,切換基本沒有內(nèi)核切換的開銷,切換靈活。

進(jìn)程和線程的關(guān)系

3.多線程

操作系統(tǒng)通過給不同的線程分配時間片(CPU運行時長)來調(diào)度線程,當(dāng)CPU執(zhí)行完一個線程的時間片后就會快速切換到下一個線程,時間片很短而且切換速度很快,以至于用戶根本察覺不到。多個線程根據(jù)分配的時間片輪流被CPU執(zhí)行,如今絕大多數(shù)計算機(jī)的CPU都是多核的,多個線程在操作系統(tǒng)的調(diào)度下,能夠被多個CPU并行執(zhí)行,程序的執(zhí)行速度和CPU的利用效率大大提升。絕大對數(shù)主流的編程語言都能很好地支持多線程,然而,Python由于GIL鎖無法實現(xiàn)真正的多線程。

內(nèi)存中的線程

4.Thread類方法

(1)start() --開始執(zhí)行該線程;

(2)run() --定義線程的方法(開發(fā)者可以在子類中重寫);標(biāo)準(zhǔn)的 run() 方法會對作為 target 參數(shù)傳遞給該對象構(gòu)造器的可調(diào)用對象(如果存在)發(fā)起調(diào)用,并附帶從 args 和 kwargs 參數(shù)分別獲取的位置和關(guān)鍵字參數(shù)。

(3)join(timeout=None) --直至啟動的線程終止之前一直掛起;除非給出了timeout(單位秒),否則一直被阻塞;因為 join() 總是返回 None ,所以要在 join() 后調(diào)用 is_alive() 才能判斷是否發(fā)生超時 -- 如果線程仍然存活,則 join() 超時。一個線程可以被 join() 很多次。如果嘗試加入當(dāng)前線程會導(dǎo)致死鎖, join() 會引起 RuntimeError 異常。如果嘗試 join() 一個尚未開始的線程,也會拋出相同的異常。

(4)is_alive() --布爾值,表示這個線程是否還存活;當(dāng) run() 方法剛開始直到 run() 方法剛結(jié)束,這個方法返回 True 。

(5)threading.current_thread()--返回當(dāng)前對應(yīng)調(diào)用者的控制線程的 Thread 對象。例如,獲取當(dāng)前線程的名字,可以是current_thread().name

5.多線程與多進(jìn)程小Case

from threading import Thread
from multiprocessing import Process
import os
def work():
    print('hello,',os.getpid())
if __name__ == '__main__':
    # 在主進(jìn)程下開啟多個線程,每個線程都跟主進(jìn)程的pid一樣
    t1 = Thread(target=work)  # 開啟一個線程
    t2 = Thread(target=work)  # 開啟兩個線程
    t1.start()  ##start()--It must be called at most once per thread object.It arranges for the object's run() method to be                ## invoked in a separate thread of control.This method will raise a RuntimeError if called more than once on the                ## same thread object.
    t2.start()
    print('主線程/主進(jìn)程pid', os.getpid())
    # 開多個進(jìn)程,每個進(jìn)程都有不同的pid
    p1 = Process(target=work)
    p2 = Process(target=work)
    p1.start()
    p2.start()
    print('主線程/主進(jìn)程pid',os.getpid())

6.Thread 的生命周期

線程的狀態(tài)包括:創(chuàng)建、就緒、運行、阻塞、結(jié)束。

(1)創(chuàng)建對象時,代表 Thread 內(nèi)部被初始化;

(2) 調(diào)用 start() 方法后,thread 會開始進(jìn)入隊列準(zhǔn)備運行,在未獲得CPU、內(nèi)存資源前,稱為就緒狀態(tài);輪詢獲取資源,進(jìn)入運行狀態(tài);如果遇到sleep,則是進(jìn)入阻塞狀態(tài);

(3) thread 代碼正常運行結(jié)束或者是遇到異常,線程會終止。

7.自定義線程

(1)定義一個類,繼承Thread;

(2)重寫__init__ 和 run();

(3)創(chuàng)建線程類對象;

(4)啟動線程。

import time
import threading
class MyThread(threading.Thread):
    def __init__(self,num):
        super().__init__() ###或者是Thread.__init__()
        self.num = num
    def run(self):
        print('線程名稱:', threading.current_thread().getName(), '參數(shù):', self.num, '開始時間:', time.strftime('%Y-%m-%d %H:%M:%S'))
if __name__ == '__main__':
    print('主線程開始:',time.strftime('%Y-%m-%d %H:%M:%S'))
    t1 = MyThread(1)
    t2 = MyThread(2)
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print('主線程結(jié)束:', time.strftime('%Y-%m-%d %H:%M:%S'))

8.線程共享數(shù)據(jù)與GIL(全局解釋器鎖)

如果是全局變量,則每個線程是共享的;

GIL鎖:可以用籃球比賽的場景來模擬,把籃球場看作是CPU,一場籃球比賽看作是一個線程,如果只有一個籃球場,多場比賽就要排隊進(jìn)行,類似于一個簡單的單核多線程的程序;如果由多塊籃球場,多場比賽同時進(jìn)行,就是一個簡單的多核多線程的程序。然而,Python有著特別的規(guī)定:每場比賽必須要在裁判的監(jiān)督之下才允許進(jìn)行,而裁判只有一個。這樣不管你有幾塊籃球場,同一時間只允許有一個場地進(jìn)行比賽,其它場地都將被閑置,其它比賽都只能等待。

9.GIL 和 Lock

GIL保證同一時間內(nèi)一個進(jìn)程可以有多個線程,但只有一個線程在執(zhí)行;鎖的目的是為了保護(hù)共享的數(shù)據(jù),同一時間只能有一個線程來修改共享的數(shù)據(jù)。

類為threading.Lock

它有兩個基本方法, acquire() 和 release() 。

當(dāng)狀態(tài)為非鎖定時, acquire() 將狀態(tài)改為 鎖定 并立即返回。當(dāng)狀態(tài)是鎖定時, acquire() 將阻塞至其他線程調(diào)用 release() 將其改為非鎖定狀態(tài),然后 acquire() 調(diào)用重置其為鎖定狀態(tài)并返回。

release() 只在鎖定狀態(tài)下調(diào)用; 它將狀態(tài)改為非鎖定并立即返回。如果嘗試釋放一個非鎖定的鎖,則會引發(fā) RuntimeError 異常。

Caese 如下:

from threading import Thread
from threading import Lock
import time
number = 0
def task(lock):
    global number
    lock.acquire() ##持有鎖
    for i in range(100000)      number += 1
    lock.release() ##釋放鎖
if __name__ == '__main__':
    lock=Lock()
    t1 = Thread(target=task,args=(lock,))
    t2 = Thread(target=task,args=(lock,))    t3 = Thread(target=task,args=(lock,))
    t1.start()    t2.start()    t3.start()    t1.join()    t2.join()    t3.join()        print('number:',number)

10.線程的信號量

class threading.Semaphore([values])

values是一個內(nèi)部計數(shù),values默認(rèn)是1,如果小于0,則會拋出 ValueError 異常,可以用于控制線程數(shù)并發(fā)數(shù)。

信號量的實現(xiàn)方式:

s=Semaphore(?)

在內(nèi)部有一個counter計數(shù)器,counter的值就是同一時間可以開啟線程的個數(shù)。每當(dāng)我們s.acquire()一次,計數(shù)器就進(jìn)行減1處理,每當(dāng)我們s.release()一次,計數(shù)器就會進(jìn)行加1處理,當(dāng)計數(shù)器為0的時候,其它的線程就處于等待的狀態(tài)。

程序添加一個計數(shù)器功能(信號量),限制一個時間點內(nèi)的線程數(shù)量,防止程序崩潰或其它異常。

Case

import time
import threading
s=threading.Semaphore(5)    #添加一個計數(shù)器
def task():
    s.acquire()    #計數(shù)器獲得鎖
    time.sleep(2)    #程序休眠2秒
    print("The task run at ",time.ctime())
    s.release()    #計數(shù)器釋放鎖

for i in range(40):
    t1=threading.Thread(target=task,args=())    #創(chuàng)建線程
    t1.start()    #啟動線程

也可以使用with操作,替代acquire ()和release(),上面的代碼調(diào)整如下:

import time
import threading
s=threading.Semaphore(5)    #添加一個計數(shù)器
def task():    with s:   ## 類似打開文件的with操作
    ##s.acquire()    #計數(shù)器獲得鎖
      time.sleep(2)    #程序休眠2秒
      print("The task run at ",time.ctime())
    ##s.release()    #計數(shù)器釋放鎖

for i in range(40):
    t1=threading.Thread(target=task,args=())    #創(chuàng)建線程
    t1.start()    #啟動線程

建議使用with。

總結(jié)

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

相關(guān)文章

  • Python實現(xiàn)的括號匹配判斷功能示例

    Python實現(xiàn)的括號匹配判斷功能示例

    這篇文章主要介紹了Python實現(xiàn)的括號匹配判斷功能,涉及Python棧與列表的存儲、遍歷、判斷等相關(guān)操作技巧,需要的朋友可以參考下
    2018-08-08
  • Python函數(shù)和模塊的使用總結(jié)

    Python函數(shù)和模塊的使用總結(jié)

    在本文中小編給大家整理了關(guān)于Python函數(shù)和模塊的使用的相關(guān)知識點以及實例代碼內(nèi)容,需要的朋友們跟著學(xué)習(xí)下。
    2019-05-05
  • Python進(jìn)度條實時顯示處理進(jìn)度的示例代碼

    Python進(jìn)度條實時顯示處理進(jìn)度的示例代碼

    本篇文章主要介紹了Python進(jìn)度條實時顯示處理進(jìn)度的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • Python實現(xiàn)讀取機(jī)器硬件信息的方法示例

    Python實現(xiàn)讀取機(jī)器硬件信息的方法示例

    這篇文章主要介紹了Python實現(xiàn)讀取機(jī)器硬件信息的方法,涉及Python針對計算機(jī)注冊表、操作系統(tǒng)、處理器、網(wǎng)絡(luò)等常見硬件信息讀取操作相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2018-06-06
  • Python正則表達(dá)式知識匯總

    Python正則表達(dá)式知識匯總

    本文介紹了Python正則表達(dá)式的相關(guān)基礎(chǔ)知識,本文的內(nèi)容不包括如何編寫高效的正則表達(dá)式、如何優(yōu)化正則表達(dá)式,這些主題請查看其他教程。
    2017-09-09
  • Python中使用HTMLParser解析html實例

    Python中使用HTMLParser解析html實例

    這篇文章主要介紹了Python中使用HTMLParser解析html實例,本文直接給出使用示例,并總結(jié)出HTMLParser含有的方法分為兩類,一類是需要顯式調(diào)用的,而另一類不需顯示調(diào)用,需要的朋友可以參考下
    2015-02-02
  • Python批量圖片去水印的方法

    Python批量圖片去水印的方法

    ​平常工作中,有時為了采用網(wǎng)絡(luò)的一些素材,但這些素材往往被打了水印,如果我們不懂PS就無法去掉水印,或者無法批量去掉水印。本文就介紹了Python批量圖片去水印的方法,感興趣的可以了解一下
    2021-05-05
  • 如何在python中執(zhí)行另一個py文件

    如何在python中執(zhí)行另一個py文件

    這篇文章主要介紹了如何在python中執(zhí)行另一個py文件,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04
  • Python + Flask 實現(xiàn)簡單的驗證碼系統(tǒng)

    Python + Flask 實現(xiàn)簡單的驗證碼系統(tǒng)

    這篇文章主要介紹了Python + Flask 制作一個簡單的驗證碼系統(tǒng),本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-10-10
  • Python的基本語法詳解

    Python的基本語法詳解

    本文詳細(xì)講解了Python的基本語法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05

最新評論

普宁市| 进贤县| 昌邑市| 宜春市| 绥滨县| 阿拉尔市| 印江| 贵港市| 兴宁市| 万源市| 徐水县| 宁津县| 淮北市| 凭祥市| 乌鲁木齐县| 富锦市| 弋阳县| 三门峡市| 马龙县| 南郑县| 普洱| 阿克| 西盟| 武冈市| 宾川县| 上虞市| 枣阳市| 胶南市| 芜湖县| 克山县| 凉城县| 邵武市| 绥化市| 天全县| 土默特右旗| 轮台县| 托里县| 临洮县| 垫江县| 新巴尔虎右旗| 凤山县|