日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python的线程组怎么写_Python学习——Python线程

發(fā)布時(shí)間:2023/12/15 python 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python的线程组怎么写_Python学习——Python线程 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、線程創(chuàng)建

1 #方法一:將要執(zhí)行的方法作為參數(shù)傳給Thread的構(gòu)造方法

2 importthreading3 importtime4

5 defshow(arg):6 time.sleep(2)7 print('thread' +str(arg))8

9 for i in range(10):10 t = threading.Thread(target=show,args=(i,))11 time.sleep(2)12 t.start()13

14 #方法2:從Thread繼承,并重寫run()

15 classMyThread(threading.Thread):16 def __init__(self,num):17 threading.Thread.__init__(self)18 self.num =num19

20 def run(self)):#定義每個(gè)線程要運(yùn)行的函數(shù)

21 print("running on number:%s" %self.num)22 time.sleep(3)23

24

25 if __name__ == '__main__':26 t1 = MyThread(1)27 t2 = MyThread(2)28 t1.start()29 time.sleep(3)30 t2.start()

注解:

Thread(group=None,target=None,name=None,args=(),kwargs={})

group:線程組,目前還沒有實(shí)現(xiàn),庫(kù)引用時(shí)提示必須是None

target:要執(zhí)行的方法

name:線程名

args/kwargs:要傳入方法的參數(shù),args和kwargs兩個(gè)參數(shù)其實(shí)是二選一

#實(shí)例方法

isAlive():返回線程是否在運(yùn)行

get/setName(name):獲取/設(shè)置線程名

is/setDaemon(bool):獲取/設(shè)置是否守護(hù)線程。初始值從創(chuàng)建該線程的線程繼承,當(dāng)沒有非守護(hù)線程仍在運(yùn)行時(shí),程序?qū)⒔K止

start():啟動(dòng)線程

join([timeout]):阻塞當(dāng)前上下文環(huán)境的線程。

二、Python多線程用法

1 importthreading2 from time importctime,sleep3

4 defmusic(func):5 for i in range(2):6 print("I was listening to %s. %s" %(func,ctime()))7 sleep(1)8 defmove(func):9 for i in range(2):10 print("I was at the %s! %s" %(func,ctime()))11 sleep(5)12

13 threads =[]14 t1 = threading.Thread(target=music,args=('童話鎮(zhèn)',))15 threads.append(t1)16 t2 = threading.Thread(target=move,args=('變形金剛',))17 threads.append(t2)18

19 if __name__ == '__main__':20 for t inthreads:21 t.setDaemon(True)22 t.start()23

24 print("all over %s" %ctime())

注:

threads?=?[]

t1?=?threading.Thread(target=music,args=('童話鎮(zhèn)',))

threads.append(t1)

創(chuàng)建了threads數(shù)組,創(chuàng)建線程t1,使用threading.Thread()方法,在這個(gè)方法中調(diào)用music方法target=music,args方法對(duì)music進(jìn)行傳參。?把創(chuàng)建好的線程t1裝到threads數(shù)組中。

接著以同樣的方式創(chuàng)建線程t2,并把t2也裝到threads數(shù)組。

for?t?in?threads:

t.setDaemon(True)

t.start()

最后通過for循環(huán)遍歷數(shù)組。(數(shù)組被裝載了t1和t2兩個(gè)線程)

setDaemon()

setDaemon(True)將線程聲明為守護(hù)線程,必須在start()?方法調(diào)用之前設(shè)置,如果不設(shè)置為守護(hù)線程程序會(huì)被無限掛起。子線程啟動(dòng)后,父線程也繼續(xù)執(zhí)行下去,當(dāng)父線程執(zhí)行完最后一條語句print?"all?over?%s"?%ctime()后,沒有等待子線程,直接就退出了,同時(shí)子線程也一同結(jié)束。

serDeamon(False)(默認(rèn))前臺(tái)線程,主線程執(zhí)行過程中,前臺(tái)線程也在進(jìn)行,主線程執(zhí)行完畢后,等待前臺(tái)線程也執(zhí)行完成后,主線程停止。

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

I was listening to 童話鎮(zhèn). Thu Jun 22 23:23:07 2017

I was at the 變形金剛! Thu Jun 22 23:23:07 2017

all over Thu Jun 22 23:23:07 2017

從執(zhí)行結(jié)果來看,子線程(muisc?、move?)和主線程(print?"all?over?%s"?%ctime())都是同一時(shí)間啟動(dòng),但由于主線程執(zhí)行完結(jié)束,所以導(dǎo)致子線程也終止。

調(diào)整程序:

1 if __name__ == '__main__':2 for t inthreads:3 t.setDaemon(True)4 t.start()5

6 t.join()7

8 print "all over %s" %ctime()

加了join()方法,用于等待線程終止。join()的作用是,在子線程完成運(yùn)行之前,這個(gè)子線程的父線程將一直被阻塞。

join()方法的位置是在for循環(huán)外的,也就是說必須等待for循環(huán)里的兩個(gè)進(jìn)程都結(jié)束后,才去執(zhí)行主進(jìn)程。

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

1 ############運(yùn)行結(jié)果###################

2 I was listening to 童話鎮(zhèn). Thu Jun 22 23:34:22 2017

3 I was at the 變形金剛! Thu Jun 22 23:34:22 2017

4 I was listening to 童話鎮(zhèn). Thu Jun 22 23:34:23 2017

5 I was at the 變形金剛! Thu Jun 22 23:34:27 2017

6 all over Thu Jun 22 23:34:32 2017

從結(jié)果的時(shí)間可以看出每首歌之間等待1秒,電影之間等待5秒,但是是同步進(jìn)行的,總的時(shí)間為5秒

三、線程鎖(LOCK,RLOCK)

由于線程之間是進(jìn)行隨機(jī)調(diào)度,并且每個(gè)線程可能只執(zhí)行n條執(zhí)行之后,當(dāng)多個(gè)線程同時(shí)修改同一條數(shù)據(jù)時(shí)可能會(huì)出現(xiàn)臟數(shù)據(jù),所以,出現(xiàn)了線程鎖 - 同一時(shí)刻允許一個(gè)線程執(zhí)行操作。

Lock(指令鎖)是可用的最低級(jí)的同步指令。Lock處于鎖定狀態(tài)時(shí),不被特定的線程擁有。Lock包含兩種狀態(tài)——鎖定和非鎖定,以及兩個(gè)基本的方法。

可以認(rèn)為L(zhǎng)ock有一個(gè)鎖定池,當(dāng)線程請(qǐng)求鎖定時(shí),將線程至于池中,直到獲得鎖定后出池。池中的線程處于狀態(tài)圖中的同步阻塞狀態(tài)。

RLock(可重入鎖)是一個(gè)可以被同一個(gè)線程請(qǐng)求多次的同步指令。RLock使用了“擁有的線程”和“遞歸等級(jí)”的概念,處于鎖定狀態(tài)時(shí),RLock被某個(gè)線程擁有。擁有RLock的線程可以再次調(diào)用acquire(),釋放鎖時(shí)需要調(diào)用release()相同次數(shù)。

可以認(rèn)為RLock包含一個(gè)鎖定池和一個(gè)初始值為0的計(jì)數(shù)器,每次成功調(diào)用 acquire()/release(),計(jì)數(shù)器將+1/-1,為0時(shí)鎖處于未鎖定狀態(tài)。

簡(jiǎn)言之:Lock屬于全局,Rlock屬于線程。

1,未使用鎖

1 importthreading2 importtime3

4 num =05

6 defshow(arg):7 globalnum8 time.sleep(1)9 num +=1

10 print(num)11

12 for i in range(10):13 t = threading.Thread(target=show, args=(i,))14 t.start()15

16 print('main thread stop')

多次運(yùn)行可能產(chǎn)生混亂。這種場(chǎng)景就是適合使用鎖的場(chǎng)景。

2.使用鎖

1 importthreading2 importtime3

4 num =05 lock =threading.RLock()6

7 #調(diào)用acquire([timeout])時(shí),線程將一直阻塞,

8 #直到獲得鎖定或者直到timeout秒后(timeout參數(shù)可選)。

9 #返回是否獲得鎖。

10 defshow(arg):11 lock.acquire()12 globalnum13 time.sleep(1)14 num +=1

15 print(num)16 lock.release()17

18 for i in range(10):19 t = threading.Thread(target=show, args=(i,))20 t.start()21

22 print('main thread stop')

加上鎖后數(shù)字會(huì)一步步打印出來,不會(huì)因?yàn)閾矶露e(cuò)亂的情況!

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

互斥鎖 同時(shí)只允許一個(gè)線程更改數(shù)據(jù),而Semaphore是同時(shí)允許一定數(shù)量的線程更改數(shù)據(jù) ,比如廁所有3個(gè)坑,那最多只允許3個(gè)人上廁所,后面的人只能等里面有人出來了才能再進(jìn)去。

1 importthreading, time2

3 defrun(n):4 semaphore.acquire()5 time.sleep(3)6 print("run the thread: %s" %n)7 semaphore.release()8

9 if __name__ == '__main__':10 num =011 semaphore = threading.BoundedSemaphore(5) #最多允許5個(gè)線程同時(shí)運(yùn)行

12 for i in range(20):13 t = threading.Thread(target=run, args=(i,))14 t.start()

五、事件(event)

Python線程的事件主要用于主線程控制其他線程的執(zhí)行,事件主要提供了三個(gè)方法:set、wait、clear

事件處理的機(jī)制:全局定義了一個(gè)“Flag”,如果“Flag”值為 False,那么當(dāng)程序執(zhí)行 event.wait 方法時(shí)就會(huì)阻塞,如果“Flag”值為True,那么event.wait 方法時(shí)便不再阻塞。

clear:將“Flag”設(shè)置為False

set:將“Flag”設(shè)置為True

用threading.Event實(shí)現(xiàn)線程間的通訊

threading.Event使一個(gè)線程等待其他線程的通知,把這個(gè)Event傳遞到線程對(duì)象中,Event默認(rèn)內(nèi)置了一個(gè)標(biāo)志,初始值為False。

一旦該線程通過wait()方法進(jìn)入等待狀態(tài),直到另一個(gè)線程調(diào)用該Event的set()方法將內(nèi)置標(biāo)志設(shè)置為True時(shí),

該Event會(huì)通知所有等待狀態(tài)的線程恢復(fù)運(yùn)行。

1 importthreading2

3 defdo(event):4 print('start')5 event.wait()6 print('end')7

8 event_obj =threading.Event()9

10 for i in range(10):11 t = threading.Thread(target=do, args=(event_obj,))12 t.start()13

14 event_obj.clear() #繼續(xù)阻塞

15

16 inp = input('input:')17 if inp == 'true':18 event_obj.set() #喚醒

六、條件(condition)

所謂條件變量,即這種機(jī)制是在滿足特定條件之后,線程才可以訪問相關(guān)的數(shù)據(jù)!

它使用Condition類來完成,由于它也可以像鎖機(jī)制那樣用,所以它也有acquire方法和release方法,而且它還有wait,notify,notifyAll方法

總結(jié)

以上是生活随笔為你收集整理的python的线程组怎么写_Python学习——Python线程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。