国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

# Python 多線程和鎖

cpupro / 3268人閱讀

摘要:多線程和鎖作者博客進(jìn)程和線程進(jìn)程是執(zhí)行中的計(jì)算機(jī)程序。線程包括開(kāi)始執(zhí)行順序和結(jié)束三部分。的多進(jìn)程相關(guān)模塊模塊是高級(jí)別的多線程模塊。線程鎖當(dāng)多線程爭(zhēng)奪鎖時(shí),允許第一個(gè)獲得鎖的線程進(jìn)入臨街區(qū),并執(zhí)行代碼。

Python 多線程和鎖

作者博客:http://zzir.cn/

進(jìn)程和線程

進(jìn)程是執(zhí)行中的計(jì)算機(jī)程序。每個(gè)進(jìn)程都擁有自己的地址空間、內(nèi)存、數(shù)據(jù)棧及其它的輔助數(shù)據(jù)。操作系統(tǒng)管理著所有的進(jìn)程,并為這些進(jìn)程合理分配時(shí)間。進(jìn)程可以通過(guò)派生新的進(jìn)程來(lái)執(zhí)行其它任務(wù),不過(guò)每個(gè)進(jìn)程都擁有自己的內(nèi)存和數(shù)據(jù)棧等,進(jìn)程之間的數(shù)據(jù)交換采用 進(jìn)程間通信(IPC) 方式。

線程在進(jìn)程之下執(zhí)行,一個(gè)進(jìn)程下可以運(yùn)行多個(gè)線程,它們之間共享相同上下文。線程包括開(kāi)始、執(zhí)行順序和結(jié)束三部分。它有一個(gè)指針,用于記錄當(dāng)前運(yùn)行的上下文。當(dāng)其它線程執(zhí)行時(shí),它可以被搶占(中斷)和臨時(shí)掛起(也稱睡眠) ——這種做法叫做 讓步(yielding)

一個(gè)進(jìn)程中的各個(gè)線程與主進(jìn)程共享同一片數(shù)據(jù)空間,與獨(dú)立進(jìn)程相比,線程之間信息共享和通信更加容易。線程一般以并發(fā)執(zhí)行,正是由于這種并發(fā)和數(shù)據(jù)共享機(jī)制,使多任務(wù)間的協(xié)作成為可能。當(dāng)然,這種共享也并不是沒(méi)有風(fēng)險(xiǎn)的,如果多個(gè)線程訪問(wèn)同一數(shù)據(jù)空間,由于訪問(wèn)順序不同,可能導(dǎo)致結(jié)果不一致,這種情況通常稱為競(jìng)態(tài)條件(race condition),不過(guò)大多數(shù)線程庫(kù)都有同步原語(yǔ),以允許線程管理器的控制執(zhí)行和訪問(wèn);另一個(gè)要注意的問(wèn)題是,線程無(wú)法給予公平執(zhí)行時(shí)間,CPU 時(shí)間分配會(huì)傾向那些阻塞更少的函數(shù)。

全局解釋器鎖(GIL)

Python 代碼執(zhí)行由 Python 虛擬機(jī) (又名解釋器主循環(huán)) 進(jìn)行控制。Python 在設(shè)計(jì)時(shí)是這樣考慮的,在主循環(huán)中同時(shí)只能有一個(gè)控制線程在執(zhí)行。對(duì) Python 虛擬機(jī)的訪問(wèn)由 全局解釋器(GIL) 控制,這個(gè)鎖用于,當(dāng)有多個(gè)線程時(shí)保證同一時(shí)刻只能有一個(gè)線程在運(yùn)行。

由于 Python 的 GIL 的限制,多線程更適合 I/O 密集型應(yīng)用( I/O 釋放了 GIL,可以允許更多的并發(fā)),對(duì)于計(jì)算密集型應(yīng)用,為了實(shí)現(xiàn)更好的并行性,適合使用多進(jìn)程,已便利用 CPU 的多核優(yōu)勢(shì)。Python 的多進(jìn)程相關(guān)模塊:subprocess、multiprocessing、concurrent.futures

threading 模塊

threading 是 Python 高級(jí)別的多線程模塊。

threading 模塊的函數(shù)

active_count() 當(dāng)前活動(dòng)的 Thread 對(duì)象個(gè)數(shù)

current_thread() 返回當(dāng)前 Thread 對(duì)象

get_ident() 返回當(dāng)前線程

enumerater() 返回當(dāng)前活動(dòng) Thread 對(duì)象列表

main_thread() 返回主 Thread 對(duì)象

settrace(func) 為所有線程設(shè)置一個(gè) trace 函數(shù)

setprofile(func) 為所有線程設(shè)置一個(gè) profile 函數(shù)

stack_size([size]) 返回新創(chuàng)建線程棧大小;或?yàn)楹罄m(xù)創(chuàng)建的線程設(shè)定棧大小為 size

TIMEOUT_MAX Lock.acquire(), RLock.acquire(), Condition.wait() 允許的最大值

threading 可用對(duì)象列表:

Thread 表示執(zhí)行線程的對(duì)象

Lock 鎖原語(yǔ)對(duì)象

RLock 可重入鎖對(duì)象,使單一進(jìn)程再次獲得已持有的鎖(遞歸鎖)

Condition 條件變量對(duì)象,使得一個(gè)線程等待另一個(gè)線程滿足特定條件,比如改變狀態(tài)或某個(gè)值

Semaphore 為線程間共享的有限資源提供一個(gè)"計(jì)數(shù)器",如果沒(méi)有可用資源會(huì)被阻塞

Event 條件變量的通用版本,任意數(shù)量的線程等待某個(gè)時(shí)間的發(fā)生,在改事件發(fā)生后所有線程被激活

Timer 與 Thread 相識(shí),不過(guò)它要在運(yùn)行前等待一段時(shí)間

Barrier 創(chuàng)建一個(gè)"阻礙",必須達(dá)到指定數(shù)量的線程后才可以繼續(xù)

Thread 類

Thread 對(duì)象的屬性有:Thread.nameThread.identThread.daemon。詳見(jiàn)(The Python Standard Library)

Thread 對(duì)象方法:
Thread.start()Thread.run()Thread.join(timeout=None)Thread.getNameThread.setNameThread.is_alive()Thread.isDaemon()Thread.setDaemon()。詳見(jiàn)(The Python Standard Library)

使用 Thread 類,可以有很多種方法來(lái)創(chuàng)建線程,這里使用常見(jiàn)的兩種:

創(chuàng)建 Thread 實(shí)例,傳給它一個(gè)函數(shù)。

派生 Thread 子類,并創(chuàng)建子類的實(shí)例。

一個(gè)單線程栗子
#!/usr/bin/env python3

import threading
from random import randint
from time import sleep, ctime

def hi(n):
    sleep(n)
    print("ZzZzzz, sleep: ", n)    # 打印 Sleep 的秒數(shù)

def main():
    print("### Start at: ", ctime())

    for i in range(10):
        hi(randint(1,2))    # 調(diào)用十次,每次 Sleep 1秒或2秒

    print("### Done at: ", ctime())

if __name__ == "__main__":
    main()

運(yùn)行結(jié)果:

### Start at:  Thu Sep  1 14:11:00 2016
ZzZzzz, sleep:  1
ZzZzzz, sleep:  2
ZzZzzz, sleep:  2
ZzZzzz, sleep:  2
ZzZzzz, sleep:  1
ZzZzzz, sleep:  1
ZzZzzz, sleep:  1
ZzZzzz, sleep:  1
ZzZzzz, sleep:  1
ZzZzzz, sleep:  2
### Done at:  Thu Sep  1 14:11:14 2016

一共是用了14秒。

多線程:創(chuàng)建 Thread 實(shí)例,傳給它一個(gè)函數(shù)

直接上代碼:

#!/usr/bin/env python3

import threading
from random import randint
from time import sleep, ctime

def hi(n):
    sleep(n)
    print("ZzZzzz, sleep: ", n)

def main():
    print("### Start at: ", ctime())
    threads = []

    for i in range(10):
        rands = randint(1,2)
        # 實(shí)例化每個(gè) Thread 對(duì)象,把函數(shù)和參數(shù)傳遞進(jìn)去,返回 Thread 實(shí)例
        t = threading.Thread(target=hi, args=(rands,))
        threads.append(t)     # 分配線程

    for i in range(10):
        threads[i].start()    # 開(kāi)始執(zhí)行多線程

    for i in range(10):
        threads[i].join()     # (自旋鎖)等待線程結(jié)束或超時(shí),然后再往下執(zhí)行

    print("### Done at: ", ctime())

if __name__ == "__main__":
    main()

運(yùn)行結(jié)果:

### Start at:  Thu Sep  1 14:18:00 2016
ZzZzzz, sleep:  1
ZzZzzz, sleep:  1
ZzZzzz, sleep:  1
ZzZzzz, sleep:  1
ZzZzzz, sleep:  1
ZzZzzz, sleep:  1
ZzZzzz, sleep:  2
ZzZzzz, sleep:  2
ZzZzzz, sleep:  2
ZzZzzz, sleep:  2
### Done at:  Thu Sep  1 14:18:02 2016

使用多線程,只用了2秒。

多線程:派生 Thread 子類,并創(chuàng)建子類的實(shí)例
#!/usr/bin/env python3

import threading
from random import randint
from time import sleep, ctime

class MyThread(threading.Thread):
 
    def __init__(self, func, args, times):
        super(MyThread, self).__init__()
        self.func = func
        self.args = args
        self.times = times
    
    def run(self):
        print("begin thread......", self.times)
        self.res = self.func(*self.args)
        print("end threads......", self.times)


def hi(n):
    sleep(n)
    print("ZzZzzz, sleep: ", n)

def main():
    print("### Start at: ", ctime())
    threads = []

    for i in range(10):
        rands = randint(1,2)
        t = MyThread(hi, (rands,), i+1)
        threads.append(t)

    for i in range(10):
        threads[i].start()

    for i in range(10):
        threads[i].join()

    print("### Done at: ", ctime())

if __name__ == "__main__":
    main()

執(zhí)行結(jié)果:

### Start at:  Thu Sep  1 14:47:09 2016
begin thread...... 1
begin thread...... 2
begin thread...... 3
begin thread...... 4
begin thread...... 5
begin thread...... 6
begin thread...... 7
begin thread...... 8
begin thread...... 9
begin thread...... 10
ZzZzzz, sleep:  1
ZzZzzz, sleep:  1
end threads...... 1
end threads...... 4
ZzZzzz, sleep:  1
end threads...... 7
ZzZzzz, sleep:  1
end threads...... 3
ZzZzzz, sleep:  1
end threads...... 9
ZzZzzz, sleep:  2
end threads...... 2
ZzZzzz, sleep:  2
end threads...... 5
ZzZzzz, sleep:  2
ZzZzzz, sleep:  2
end threads...... 10
end threads...... 6
ZzZzzz, sleep:  2
end threads...... 8
### Done at:  Thu Sep  1 14:47:11 2016

這個(gè)栗子對(duì) Thread 子類化,而不是對(duì)其實(shí)例化,使得定制線程對(duì)象更具靈活性,同時(shí)也簡(jiǎn)化線程創(chuàng)建的調(diào)用過(guò)程。

線程鎖

當(dāng)多線程爭(zhēng)奪鎖時(shí),允許第一個(gè)獲得鎖的線程進(jìn)入臨街區(qū),并執(zhí)行代碼。所有之后到達(dá)的線程將被阻塞,直到第一個(gè)線程執(zhí)行結(jié)束,退出臨街區(qū),并釋放鎖。需要注意,那些阻塞的線程是沒(méi)有順序的。

舉個(gè)栗子:

#!/usr/bin/env python3

import threading
from random import randint
from time import sleep, ctime

L = threading.Lock() # 引入鎖

def hi(n):
    L.acquire()    # 加鎖
    for i in [1,2]:
        print(i)
        sleep(n)
        print("ZzZzzz, sleep: ", n)
    L.release()    # 釋放鎖

def main():
    print("### Start at: ", ctime())
    threads = []

    for i in range(10):
        rands = randint(1,2)
        t = threading.Thread(target=hi, args=(rands,))
        threads.append(t)

    for i in range(10):
        threads[i].start()

    for i in range(10):
        threads[i].join()

    print("### Done at: ", ctime())

if __name__ == "__main__":
    main()

運(yùn)行上面的代碼,再將鎖的代碼注釋掉,對(duì)比下輸出。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/38155.html

相關(guān)文章

  • Java 8 并發(fā):同步和鎖

    摘要:可重入意味著鎖被綁定到當(dāng)前線程,線程可以安全地多次獲取相同的鎖,而不會(huì)發(fā)生死鎖例如同步方法在同一對(duì)象上調(diào)用另一個(gè)同步方法。寫(xiě)入鎖釋放后,兩個(gè)任務(wù)并行執(zhí)行,它們不必等待對(duì)方是否完成,因?yàn)橹灰獩](méi)有線程持有寫(xiě)入鎖,它們就可以同時(shí)持有讀取鎖。 原文地址: Java 8 Concurrency Tutorial: Synchronization and Locks 為了簡(jiǎn)單起見(jiàn),本教程的示例代...

    andycall 評(píng)論0 收藏0
  • Java 8 并發(fā)教程:同步和鎖

    摘要:在接下來(lái)的分鐘,你將會(huì)學(xué)會(huì)如何通過(guò)同步關(guān)鍵字,鎖和信號(hào)量來(lái)同步訪問(wèn)共享可變變量。所以在使用樂(lè)觀鎖時(shí),你需要每次在訪問(wèn)任何共享可變變量之后都要檢查鎖,來(lái)確保讀鎖仍然有效。 原文:Java 8 Concurrency Tutorial: Synchronization and Locks譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 歡迎閱讀我的Java8并發(fā)教程的第二部分。這份指南將...

    wyk1184 評(píng)論0 收藏0
  • python并發(fā)4:使用thread處理并發(fā)

    摘要:如果某線程并未使用很多操作,它會(huì)在自己的時(shí)間片內(nèi)一直占用處理器和。在中使用線程在和等大多數(shù)類系統(tǒng)上運(yùn)行時(shí),支持多線程編程。守護(hù)線程另一個(gè)避免使用模塊的原因是,它不支持守護(hù)線程。 這一篇是Python并發(fā)的第四篇,主要介紹進(jìn)程和線程的定義,Python線程和全局解釋器鎖以及Python如何使用thread模塊處理并發(fā) 引言&動(dòng)機(jī) 考慮一下這個(gè)場(chǎng)景,我們有10000條數(shù)據(jù)需要處理,處理每條...

    joywek 評(píng)論0 收藏0
  • Python進(jìn)程專題5:進(jìn)程間通信

    摘要:上一篇文章進(jìn)程專題進(jìn)程池下一篇文章進(jìn)程專題共享數(shù)據(jù)與同步模塊支持的進(jìn)程間通信主要有兩種管道和隊(duì)列。隊(duì)列底層使用管道和鎖,同時(shí)運(yùn)行支持線程講隊(duì)列中的數(shù)據(jù)傳輸?shù)降讓庸艿乐校瑏?lái)實(shí)習(xí)進(jìn)程間通信。 上一篇文章:Python進(jìn)程專題4:進(jìn)程池Pool下一篇文章:Python進(jìn)程專題6:共享數(shù)據(jù)與同步 multiprocessing模塊支持的進(jìn)程間通信主要有兩種:管道和隊(duì)列。一般來(lái)說(shuō),發(fā)送較少的大...

    eccozhou 評(píng)論0 收藏0
  • 不可不說(shuō)的Java“鎖”事

    摘要:本文旨在對(duì)鎖相關(guān)源碼本文中的源碼來(lái)自使用場(chǎng)景進(jìn)行舉例,為讀者介紹主流鎖的知識(shí)點(diǎn),以及不同的鎖的適用場(chǎng)景。中,關(guān)鍵字和的實(shí)現(xiàn)類都是悲觀鎖。自適應(yīng)意味著自旋的時(shí)間次數(shù)不再固定,而是由前一次在同一個(gè)鎖上的自旋時(shí)間及鎖的擁有者的狀態(tài)來(lái)決定。 前言 Java提供了種類豐富的鎖,每種鎖因其特性的不同,在適當(dāng)?shù)膱?chǎng)景下能夠展現(xiàn)出非常高的效率。本文旨在對(duì)鎖相關(guān)源碼(本文中的源碼來(lái)自JDK 8)、使用場(chǎng)景...

    galaxy_robot 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<