線程實(shí)戰(zhàn)

多線程-threading

python的thread模塊是比較底層的模塊,python的threading模塊是對(duì)thread做了一些包裝的,可以更加方便的被使用

1.可以明顯看出使用了多線程并發(fā)的操作,花費(fèi)時(shí)間要短很多

2.創(chuàng)建好的線程,需要調(diào)用start()方法來啟動(dòng)

線程的執(zhí)行順序

結(jié)果來看:主線程會(huì)等待所有的子線程結(jié)束后才結(jié)束


從代碼和執(zhí)行結(jié)果我們可以看出,多線程程序的執(zhí)行順序是不確定的。當(dāng)執(zhí)行到sleep語句時(shí),線程將被阻塞(Blocked),到sleep結(jié)束后,線程進(jìn)入就緒(Runnable)狀態(tài),等待調(diào)度。而線程調(diào)度將自行選擇一個(gè)線程執(zhí)行。上面的代碼中只能保證每個(gè)線程都運(yùn)行完整個(gè)run函數(shù),但是線程的啟動(dòng)順序、run函數(shù)中每次循環(huán)的執(zhí)行順序都不能確定。

查看線程數(shù)量


線程中的守護(hù)進(jìn)程

線程執(zhí)行代碼的封裝

通過使用threading模塊能完成多任務(wù)的程序開發(fā),為了讓每個(gè)線程的封裝性更完美,所以使用threading模塊時(shí),往往會(huì)定義一個(gè)新的子類class,只要繼承threading.Thread就可以了,然后重寫run方法

說明

·python的threading.Thread類有一個(gè)run方法,用于定義線程的功能函數(shù),可以在自己的線程類中覆蓋該方法。而創(chuàng)建自己的線程實(shí)例后,通過Thread類的start方法,可以啟動(dòng)該線程,交給python虛擬機(jī)進(jìn)行調(diào)度,當(dāng)該線程獲得執(zhí)行的機(jī)會(huì)時(shí),就會(huì)調(diào)用run方法執(zhí)行線程。

多線程-共享全局變量



總結(jié):

·在一個(gè)進(jìn)程內(nèi)的所有線程共享全局變量,能夠在不適用其他方式的前提下完成多線程之間的數(shù)據(jù)共享(這點(diǎn)要比多進(jìn)程要好)

·缺點(diǎn)就是,線程是對(duì)全局變量隨意遂改可能造成多線程之間對(duì)全局變量的混亂(即線程非安全)

進(jìn)程VS線程

·進(jìn)程,能夠完成多任務(wù),比如?在一臺(tái)電腦上能夠同時(shí)運(yùn)行多個(gè)QQ

·線程,能夠完成多任務(wù),比如?一個(gè)QQ中的多個(gè)聊天窗口

定義的不同

·進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位.

·線程是進(jìn)程的一個(gè)實(shí)體,是CPU調(diào)度和分派的基本單位,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位.線程自己基本上不擁有系統(tǒng)資源,只擁有一點(diǎn)在運(yùn)行中必不可少的資源(如程序計(jì)數(shù)器,一組寄存器和棧),但是它可與同屬一個(gè)進(jìn)程的其他的線程共享進(jìn)程所擁有的全部資源.

區(qū)別

·一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程.

·線程的劃分尺度小于進(jìn)程(資源比進(jìn)程少),使得多線程程序的并發(fā)性高。

·進(jìn)程在執(zhí)行過程中擁有獨(dú)立的內(nèi)存單元,而多個(gè)線程共享內(nèi)存,從而極大地提高了程序的運(yùn)行效率

·線程不能夠獨(dú)立執(zhí)行,必須依存在進(jìn)程中

優(yōu)缺點(diǎn)

線程和進(jìn)程在使用上各有優(yōu)缺點(diǎn):線程執(zhí)行開銷小,但不利于資源的管理和保護(hù);而進(jìn)程正相反。

同步的概念

1.多線程開發(fā)可能遇到的問題

同步不是一起的意思,是協(xié)同步調(diào)

2.什么是同步

同步就是協(xié)同步調(diào),按預(yù)定的先后次序進(jìn)行運(yùn)行。如:你說完,我再說。

"同"字從字面上容易理解為一起動(dòng)作

其實(shí)不是,"同"字應(yīng)是指協(xié)同、協(xié)助、互相配合。

如進(jìn)程、線程同步,可理解為進(jìn)程或線程A和B一塊配合,A執(zhí)行到一定程度時(shí)要依靠B的某個(gè)結(jié)果,于是停下來,示意B運(yùn)行;B依言執(zhí)行,再將結(jié)果給A;A再繼續(xù)操作。

3.解決問題的思路

對(duì)于本小節(jié)提出的那個(gè)計(jì)算錯(cuò)誤的問題,可以通過線程同步來進(jìn)行解決

思路,如下:

1.系統(tǒng)調(diào)用t1,然后獲取到num的值為0,此時(shí)上一把鎖,即不允許其他現(xiàn)在操作num

2.對(duì)num的值進(jìn)行+1

3.解鎖,此時(shí)num的值為1,其他的線程就可以使用num了,而且是num的值不是0而是1

4.同理其他線程在對(duì)num進(jìn)行修改時(shí),都要先上鎖,處理完后再解鎖,在上鎖的整個(gè)過程中不允許其他線程訪問,就保證了數(shù)據(jù)的正確性

互斥鎖

當(dāng)多個(gè)線程幾乎同時(shí)修改某一個(gè)共享數(shù)據(jù)的時(shí)候,需要進(jìn)行同步控制

線程同步能夠保證多個(gè)線程安全訪問競(jìng)爭(zhēng)資源,最簡(jiǎn)單的同步機(jī)制是引入互斥鎖。

互斥鎖為資源引入一個(gè)狀態(tài):鎖定/非鎖定。

某個(gè)線程要更改共享數(shù)據(jù)時(shí),先將其鎖定,此時(shí)資源的狀態(tài)為“鎖定”,其他線程不能更改;直到該線程釋放資源,將資源的狀態(tài)變成“非鎖定”,其他的線程才能再次鎖定該資源?;コ怄i保證了每次只有一個(gè)線程進(jìn)行寫入操作,從而保證了多線程情況下數(shù)據(jù)的正確性。

引出鎖

鎖的實(shí)例1:

上鎖解鎖過程

當(dāng)一個(gè)線程調(diào)用鎖的acquire()方法獲得鎖時(shí),鎖就進(jìn)入“l(fā)ocked”狀態(tài)。

每次只有一個(gè)線程可以獲得鎖。如果此時(shí)另一個(gè)線程試圖獲得這個(gè)鎖,該線程就會(huì)變?yōu)椤癰locked”狀態(tài),稱為“阻塞”,直到擁有鎖的線程調(diào)用鎖的release()方法釋放鎖之后,鎖進(jìn)入“unlocked”狀態(tài)。

線程調(diào)度程序從處于同步阻塞狀態(tài)的線程中選擇一個(gè)來獲得鎖,并使得該線程進(jìn)入運(yùn)行(running)狀態(tài)。

總結(jié)

鎖的好處:

·確保了某段關(guān)鍵代碼只能由一個(gè)線程從頭到尾完整地執(zhí)行

鎖的壞處:

·阻止了多線程并發(fā)執(zhí)行,包含鎖的某段代碼實(shí)際上只能以單線程模式執(zhí)行,效率就大大地下降了

·由于可以存在多個(gè)鎖,不同的線程持有不同的鎖,并試圖獲取對(duì)方持有的鎖時(shí),可能會(huì)造成死鎖

多線程-非共享數(shù)

對(duì)于全局變量,在多線程中要格外小心,否則容易造成數(shù)據(jù)錯(cuò)亂的情況發(fā)生

1.非全局變量是否要加鎖呢?

結(jié)論:·在多線程開發(fā)中,全局變量是多個(gè)線程都共享的數(shù)據(jù),而局部變量等是各自線程的,是非共享的

死鎖

在線程間共享多個(gè)資源的時(shí)候,如果兩個(gè)線程分別占有一部分資源并且同時(shí)等待對(duì)方的資源,就會(huì)造成死鎖。

盡管死鎖很少發(fā)生,但一旦發(fā)生就會(huì)造成應(yīng)用的停止響應(yīng)

同步應(yīng)用

多個(gè)線程有序執(zhí)行

·可以使用互斥鎖完成多個(gè)任務(wù),有序的進(jìn)程工作,這就是線程的同步

生產(chǎn)者與消費(fèi)者模式

3.?Queue的說明

1.對(duì)于Queue,在多線程通信之間扮演重要的角色

2.添加數(shù)據(jù)到隊(duì)列中,使用put()方法

3.從隊(duì)列中取數(shù)據(jù),使用get()方法

4.判斷隊(duì)列中是否還有數(shù)據(jù),使用qsize()方法

4.生產(chǎn)者消費(fèi)者模式的說明

·為什么要使用生產(chǎn)者和消費(fèi)者模式

在線程世界里,生產(chǎn)者就是生產(chǎn)數(shù)據(jù)的線程,消費(fèi)者就是消費(fèi)數(shù)據(jù)的線程。在多線程開發(fā)當(dāng)中,如果生產(chǎn)者處理速度很快,而消費(fèi)者處理速度很慢,那么生產(chǎn)者就必須等待消費(fèi)者處理完,才能繼續(xù)生產(chǎn)數(shù)據(jù)。同樣的道理,如果消費(fèi)者的處理能力大于生產(chǎn)者,那么消費(fèi)者就必須等待生產(chǎn)者。為了解決這個(gè)問題于是引入了生產(chǎn)者和消費(fèi)者模式。

·什么是生產(chǎn)者消費(fèi)者模式

生產(chǎn)者消費(fèi)者模式是通過一個(gè)容器來解決生產(chǎn)者和消費(fèi)者的強(qiáng)耦合問題。生產(chǎn)者和消費(fèi)者彼此之間不直接通訊,而通過阻塞隊(duì)列來進(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)者的處理能力。

這個(gè)阻塞隊(duì)列就是用來給生產(chǎn)者和消費(fèi)者解耦的??v觀大多數(shù)設(shè)計(jì)模式,都會(huì)找一個(gè)第三者出來進(jìn)行解耦,

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.進(jìn)程和線程 隊(duì)列:1、進(jìn)程之間的通信: q = multiprocessing.Queue()2、...
    一只寫程序的猿閱讀 1,242評(píng)論 0 17
  • 下面是我自己收集整理的Java線程相關(guān)的面試題,可以用它來好好準(zhǔn)備面試。 參考文檔:-《Java核心技術(shù) 卷一》-...
    阿呆變Geek閱讀 15,142評(píng)論 14 507
  • Java-Review-Note——4.多線程 標(biāo)簽: JavaStudy PS:本來是分開三篇的,后來想想還是整...
    coder_pig閱讀 1,772評(píng)論 2 17
  • 現(xiàn)在流行很多網(wǎng)絡(luò)名言,有一句話形容現(xiàn)在的人相處是,一言不合就翻船。 隨著社會(huì)文化越來越開放化和多元化,每個(gè)的信仰和...
    歐陽修閱讀 505評(píng)論 0 0
  • 給電腦用戶加權(quán)限:1.前往文件夾 /usr 2.找到local文件夾,右鍵顯示簡(jiǎn)介,底部鎖頭解鎖,加用戶,應(yīng)用到包...
    KeepFighting閱讀 6,174評(píng)論 0 2

友情鏈接更多精彩內(nèi)容