久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

理解 python 中多線程

 ly88 2018-03-03

線程的有兩種使用方法,,一種是在函數(shù)使用,一種是放在類中使用

1,,在函數(shù)中使用多線程

語(yǔ)法如下:

1
thread.start_new_thread(function, args[, kwargs] )

參數(shù)說(shuō)明:

1
2
3
function - 線程函數(shù)。
args - 傳遞給線程函數(shù)的參數(shù),必須是個(gè)tuple類型,。
kwargs - 可選參數(shù),。

下面是一個(gè)例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def run(num):
    print 'hi , i am a thread.', num
def main():
    threads = []
    for i in range(5):
        t = threading.Thread(target=run, args=(i,))
        threads.append(t)
        t.start()
    for t in threads:
        t.join()
if __name__ == '__main__':
    print 'start -->'
    main()
    print 'go here -->'

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

1
2
3
4
5
6
7
start -->
hi , i am a thread. 0
hi , i am a thread. 1
hi , i am a thread. 2
hi , i am a thread. 3
hi , i am a thread. 4
go here -->

2,在類中多使用線程

下面是在類中使用線程的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class MyThread(threading.Thread):
    def __init__(self,num):
        self.num = num
        super(MyThread, self).__init__()
    def run(self):
        print 'i am a thread,',self.num
        time.sleep(1)
def main():
    threads = []
    for i in range(5):
        t = MyThread(i)
        threads.append(t)
        t.start()
    for t in threads:
        t.join()
if __name__ == '__main__':
    print 'start -->'
    main()
    print 'go here -->

  • run(),,需要重寫(xiě),,編寫(xiě)代碼實(shí)現(xiàn)所需要的功能。
  • getName(),,獲得線程對(duì)象名稱
  • setName(),,設(shè)置線程對(duì)象名稱
  • start(),啟動(dòng)線程
  • join([timeout]),,等待另一線程結(jié)束后再運(yùn)行,。
  • setDaemon(bool),設(shè)置子線程是否隨主線程一起結(jié)束,,必須在start() 之前調(diào)用,,默認(rèn)為False
  • isDaemon(),,判斷線程是否隨主線程一起結(jié)束,。
  • isAlive(),檢查線程是否在運(yùn)行中,。

join方法的作用是阻塞主進(jìn)程(無(wú)法執(zhí)行join以后的語(yǔ)句),,主線程等待這個(gè)線程結(jié)束后,才可以執(zhí)行下一條指令,。多線程多join的情況下,,依次執(zhí)行各線程的join方法,前頭一個(gè)結(jié)束了才能執(zhí)行后面一個(gè),。無(wú)參數(shù),,則等待到該線程結(jié)束,才開(kāi)始執(zhí)行下一個(gè)線程的join,。設(shè)置參數(shù)后,,則等待該線程這么長(zhǎng)時(shí)間就不管它了(而該線程并沒(méi)有結(jié)束)。不管的意思就是可以執(zhí)行后面的主進(jìn)程了,。

3,,線程同步與互斥鎖

線程之所以比進(jìn)程輕量,其中一個(gè)原因就是他們共享內(nèi)存,。也就是各個(gè)線程可以平等的訪問(wèn)內(nèi)存的數(shù)據(jù),,如果在短時(shí)間“同時(shí)并行”讀取修改內(nèi)存的數(shù)據(jù),,很可能造成數(shù)據(jù)不同步。例如下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var = 0
class IncreThread(Thread):
    def run(self):
        global var
        print 'before,var is ',var
        var += 1
        print 'after,var is ',var
def use_incre_thread():
    threads = []
    for i in range(50):
        t = IncreThread()
        threads.append(t)
        t.start()
    for t in threads:
        t.join()
    print 'After 10 times,var is ',var
if __name__ == '__main__':
    use_incre_thread()

有一個(gè)全局變量var,,五十個(gè)線程,,每個(gè)線程對(duì)var變量進(jìn)行加 1 運(yùn)算,但是當(dāng)你多運(yùn)行幾次后,,發(fā)現(xiàn)并不是每次的運(yùn)行結(jié)果都是 50,,為什么呢?

var是 10 的時(shí)候,,線程t1讀取了var,,這個(gè)時(shí)刻cpu將控制權(quán)給了另一個(gè)線程t2t2線程讀到的var也是 10,,t1t2都把var加到 11,,當(dāng)時(shí)我們期望的是t1 t2兩個(gè)線程使var + 2 變成 12。在這里就有了資源競(jìng)爭(zhēng),,相同的情況也可能發(fā)生在其它的線程間,,所以出現(xiàn)了最后的結(jié)果小于 50 的情況。

為了避免線程不同步造成數(shù)據(jù)不同步,,可以對(duì)資源進(jìn)行加鎖,。也就是訪問(wèn)資源的線程需要獲得鎖,才能訪問(wèn),。threading 模塊提供了一個(gè) Lock 功能,,修改代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var = 0
lock = Lock()  #創(chuàng)建鎖
class IncreThread(Thread):
    def run(self):
        global var
        lock.acquire()  #獲取鎖
        print 'before,var is ',var
        var += 1
        print 'after,var is ',var
        lock.release()  #釋放鎖
def use_incre_thread():
    threads = []
    for i in range(50):
        t = IncreThread()
        threads.append(t)
        t.start()
    for t in threads:
        t.join()
    print 'After 10 times,var is ',var
if __name__ == '__main__':
    use_incre_thread()

雖然線程可以共享內(nèi)存,,但是一個(gè)線程不能影響其他線程內(nèi)的變量(非全局變量),。

4,死鎖

在線程間共享多個(gè)資源的時(shí)候,,如果兩個(gè)線程分別占有一部分資源并且同時(shí)等待對(duì)方的資源,,就會(huì)造成死鎖。盡管死鎖很少發(fā)生,,但一旦發(fā)生就會(huì)造成應(yīng)用的停止響應(yīng),。下面是一個(gè)死鎖的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
mutex_a = Lock()
mutex_b = Lock()
class MyThread(Thread):
    def task_b(self):
        if mutex_a.acquire():
            print 'thread get a mutex_a',self.name
            time.sleep(1)
            if mutex_b.acquire():
                print 'get a mutex_b',self.name
                mutex_b.release()
            mutex_a.release()
    def task_a(self):
        if mutex_b.acquire():
            print 'thread get a mutex_b',self.name
            time.sleep(1)
            if mutex_a.acquire():
                print 'get a mutex_a',self.name
                mutex_a.release()
            mutex_b.release()
    def run(self):
        self.task_a()
        self.task_b()
if __name__ == '__main__':
    threads = [MyThread() for i in range(2)]
    print threads
    for t in threads:
        t.start()

線程需要執(zhí)行兩個(gè)任務(wù),兩個(gè)任務(wù)都需要獲取鎖,,當(dāng)兩個(gè)任務(wù)得到鎖后,,就需要等另外鎖釋放。

5,,可重入鎖

為了支持在同一線程中多次請(qǐng)求同一資源,,python 提供了可重入鎖(RLock)。RLock內(nèi)部維護(hù)著一個(gè)Lock和一個(gè)counter變量,,counter記錄了acquire的次數(shù),,從而使得資源可以被多次require,。直到一個(gè)線程所有的acquire都被release,其他的線程才能獲得資源,。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mutex = threading.RLock()
class MyThread(threading.Thread):
    def run(self):
        if mutex.acquire(1):
            print 'threading gte mutex:',self.name
            time.sleep(1)
            mutex.acquire()
            mutex.release()
            mutex.release()
def main():
    print 'start main threading:'
    threads = [MyThread() for i in range(2)]
    for t in threads:
        t.start()
    for t in threads:
        t.join()
    print 'end main threading.'
if __name__ == '__main__':        
    main()

6,,后臺(tái)線程

使用多線程默認(rèn)情況下,當(dāng)主線程退出之后,,即使子線程沒(méi)有 join,,子線程也依然會(huì)繼續(xù)執(zhí)行。如果希望主線程退出后,,其子線程也退出而不再執(zhí)行,,則需要設(shè)置子線程為后臺(tái)線程。python提供了setDaemon方法,,將子線程與主線程進(jìn)行綁定,,當(dāng)主線程退出時(shí)子線程的生命也隨之結(jié)束。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class MyThread(threading.Thread):
    def run(self):
        wait_time = random.randrange(1, 10)
        print 'thread %s will wait %s s' %(self.name, wait_time)
        time.sleep(wait_time)
        time.sleep(30)
        print 'thread %s finished.' % self.name
def main():
    print 'start thread:'
    for i in range(3):
        t = MyThread()
        t.setDaemon(1)
        t.start()
    print 'end thread.'
if __name__ == '__main__':
    main()

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

1
2
3
4
5
start thread:
thread Thread-1 will wait 9 s
thread Thread-2 will wait 1 s
thread Thread-3 will wait 7 s
end thread.

本來(lái)子線程需要等待幾秒才能結(jié)束,,但是主線程提前結(jié)束了,,所以子線程也隨主線程結(jié)束了。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多