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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多线程介绍和多线程模块-lock-互斥锁

發(fā)布時間:2023/12/4 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程介绍和多线程模块-lock-互斥锁 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

多線程介紹和多線程模塊


線程的特點:

線程的生命周期

開始

運行

結(jié)束


線程的退出:

進程執(zhí)行完成

線程的退出方法

python的系統(tǒng)推出


模塊函數(shù)

start_new_thread(func, args) #(func,(name,i))

allocate_lock()

exit()

[root@133?managehosts]#?vim?thread01.py?#!/usr/bin/env?python #encoding:utf8 import?thread import?time def?func(name?,?i):for?n?in?xrange(i):print?name,?ntime.sleep(1)thread.start_new_thread(func,('聲音',?3))?#(func,(name?,?i)) thread.start_new_thread(func,('畫面',?3))time.sleep(3) [root@133?managehosts]#?python?thread01.py? 聲音?0 畫面?0 聲音?1 畫面?1 聲音?2 畫面?2


LockType對象方法

lock= thread.allocate_lock() 生成鎖對象

lock.acquire() ? 加鎖

lock.locked() ? ? 查看鎖狀態(tài)

lock.release() ? ?多線程調(diào)度釋放鎖,使用前線程必須已經(jīng)獲得鎖定,否則將拋出異常

[root@133?managehosts]#?vim?thread01.py?#!/usr/bin/env?python #encoding:utf8 import?thread import?time def?func(name?,?i,?l):for?n?in?xrange(i):print?name,?ntime.sleep(1)l.release()??#release解鎖lock?=?thread.allocate_lock()?#申請一把鎖 lock.acquire()??#獲取并使用這把鎖thread.start_new_thread(func,('聲音',?5,?lock)) thread.start_new_thread(func,('畫面',?5,?lock))while?lock.locked():?#這是主進程,lock.locked=True,執(zhí)行pass,主進程一直處于鎖定狀態(tài),線程執(zhí)行,直到線程執(zhí)行完畢,釋放鎖,lock.locked=Falsepassprint?lock.locked()?#解鎖后,值為False print?"Exit?main?process"[root@133?managehosts]#?python?thread01.py? 聲音?畫面?00畫面?1 聲音?1 畫面?2 聲音?2 畫面?3 聲音?3 畫面?4 聲音?4 False Exit?main?process[root@133?managehosts]#?vim?thread02.py? #!/usr/bin/env?python import?thread import?timedef?printworld():for?i?in?range(5):if?w_lock.acquire():print?'world',time.ctime()h_lock.release()h_lock?=?thread.allocate_lock() w_lock?=?thread.allocate_lock()thread.start_new_thread(printworld,?())w_lock.acquire() for?i?in?range(5):if?h_lock.acquire():print?'hello',w_lock.release()time.sleep(1) [root@133?managehosts]#?python?thread02.py? hello?world?Fri?Feb?10?20:26:51?2017 hello?world?Fri?Feb?10?20:26:51?2017 hello?world?Fri?Feb?10?20:26:51?2017 hello?world?Fri?Feb?10?20:26:51?2017 hello?world?Fri?Feb?10?20:26:51?2017[root@133?managehosts]#?vim?thread02.py? #!/usr/bin/env?python import?thread import?timedef?printworld():for?i?in?range(5):if?w_lock.acquire():??#申請world鎖,if?True為真print?'world',time.ctime()?#打印worldh_lock.release()???#釋放hello鎖h_lock?=?thread.allocate_lock() w_lock?=?thread.allocate_lock()thread.start_new_thread(printworld,?())?#開啟的線程,和主進程并列執(zhí)行。w_lock.acquire()???#獲得world鎖 for?i?in?range(5):if?h_lock.acquire():?#申請hello鎖,if?True為真print?'hello',???#打印hellow_lock.release()?#釋放world鎖while?h_lock.locked():?#這是主進程,直到hello打印5次后才釋放。pass[root@133?managehosts]#?python?thread02.py? hello?world?Fri?Feb?10?20:29:48?2017 hello?world?Fri?Feb?10?20:29:48?2017 hello?world?Fri?Feb?10?20:29:48?2017 hello?world?Fri?Feb?10?20:29:48?2017 hello?world?Fri?Feb?10?20:29:48?2017


申請了鎖之后,會執(zhí)行thread.start_new_thread(func,('聲音',5,lock))和thread.start_new_thread(func,('畫面',5,lock))這兩行代碼的。

執(zhí)行他們的時候,同時也會執(zhí)行主進程里的while的。主進程與這兩個線程是同時執(zhí)行的。為了不讓線程退出,所以在主進程里有while來判斷鎖是不是已經(jīng)釋放了,如果是釋放了,說明線程執(zhí)行完了。


使用主線程控制,線程打印hello和world

[root@133?managehosts]#?vim?thread03.py?+22#!/usr/bin/env?pythonimport?thread import?timedef?hello():for?i?in?xrange(5):h_lock.acquire()print?'hello',w_lock.release()def?world():for?i?in?xrange(5):w_lock.acquire()print?'world',time.ctime()h_lock.release()?lock.release()#釋放主線程的的鎖lock?=?thread.allocate_lock()?#為主進程申請鎖 lock.acquire()??????#主進程獲得鎖h_lock?=?thread.allocate_lock()??#為hello線程申請一把鎖 w_lock?=?thread.allocate_lock()??#為world線程申請一把鎖 w_lock.acquire()?????????????????#world線程獲取鎖 thread.start_new_thread(hello,())#啟動線程hello thread.start_new_thread(world,())#啟動線程world#time.sleep(1) while?lock.locked():???#當(dāng)主線程的鎖的狀態(tài)為true時?pass???????????????#什么都不做#hello?和?world?的兩個線程是同時運行的??? [root@133?managehosts]#?python?thread03.py? hello?world?Tue?Feb?14?14:59:11?2017 hello?world?Tue?Feb?14?14:59:11?2017 hello?world?Tue?Feb?14?14:59:11?2017 hello?world?Tue?Feb?14?14:59:11?2017 hello?world?Tue?Feb?14?14:59:11?2017


從腳本的執(zhí)行順序,hello()這個函數(shù)先執(zhí)行,輸出hello,
然后把world的鎖釋放(w_lock.release())。
world()函數(shù)獲得鎖,輸出world,然后把hello的鎖釋放。
必須釋放對方的鎖,對方才能獲得鎖(h_lock.acquire()),如果對方的鎖沒有被釋放,那么對方再想獲得鎖是不成功的,會一直處于阻塞狀態(tài),直到鎖被釋放。


hello()函數(shù)第一次獲得了鎖資源(h_lock.acquire()),打印了hello,接著釋放了world的鎖資源(w_lock.release())。
world()函數(shù)獲得了鎖資源(w_lock.acquire()),打印了world,接著釋放了hello的鎖資源(h_lock.release())。
由于hello的鎖資源被釋放了,hello函數(shù)里又獲得了鎖資源,接著第二次打印hello。
也就是說哪個函數(shù)或得了鎖資源,就會打印相應(yīng)的信息。
鎖資源只有被釋放了,下一次才能獲得,即已經(jīng)獲得了鎖資源,不能再次獲得,所以在hello函數(shù)里釋放world的鎖資源,在world函數(shù)里才能獲得鎖資源。
這樣反反復(fù)復(fù),就打印了hello world。



threading


threading不需要進程的控制來控制線程

threading.Thread:類

成員方法:

start() 啟動線程

run() ? 可以重寫

join() ? 阻塞

getName()

setName()

isDaemon()判斷線程是否隨主線程一起結(jié)束

setDaemon設(shè)置線程與主線程一起結(jié)束


In?[1]:?import?threadingIn?[2]:?help(threading.Thread) Help?on?class?Thread?in?module?threading: class?Thread(_Verbose)|??Method?resolution?order:|??????Thread|??????_Verbose|??????__builtin__.object|??|??Methods?defined?here:|??|??__init__(self,?group=None,?target=None,?name=None,?args=(),?kwargs=None,?verbose=None)[root@133?managehosts]#?vim?threading01.py#!/usr/bin/env?pythonimport?threading import?timedef?func():print?'hello',time.ctime()time.sleep(1)if?__name__?==?'__main__':for?i?in?xrange(10):t?=?threading.Thread(target=func,?args?=())t.start() print?'complete'[root@133?managehosts]#?python?threading01.py hello?Tue?Feb?14?15:42:10?2017?#瞬間打印10行 hello?Tue?Feb?14?15:42:10?2017 hello?Tue?Feb?14?15:42:10?2017 hello?Tue?Feb?14?15:42:10?2017 hello?Tue?Feb?14?15:42:10?2017 hello?Tue?Feb?14?15:42:10?2017 hello?Tue?Feb?14?15:42:10?2017 hello?Tue?Feb?14?15:42:10?2017 hello?Tue?Feb?14?15:42:10?2017 hello?Tue?Feb?14?15:42:10?2017 complete


如果添加t.join,則會阻塞,每秒打印一次,上一個阻塞執(zhí)行完才會執(zhí)行下一個

def?func():print?'hello',time.ctime()time.sleep(1)if?__name__?==?'__main__':for?i?in?xrange(10):t?=?threading.Thread(target=func,?args?=())t.start()t.join() [root@133?managehosts]#?python?threading01.py?? hello?Tue?Feb?14?15:42:10?2017?#每隔一秒打印一次 hello?Tue?Feb?14?15:42:10?2017 hello?Tue?Feb?14?15:42:10?2017 hello?Tue?Feb?14?15:42:10?2017 hello?Tue?Feb?14?15:42:10?2017 hello?Tue?Feb?14?15:42:10?2017 hello?Tue?Feb?14?15:42:10?2017 hello?Tue?Feb?14?15:42:10?2017 hello?Tue?Feb?14?15:42:10?2017 hello?Tue?Feb?14?15:42:10?2017 complete


[root@133?managehosts]#?vim?threading02.py? #!/usr/bin/env?python #encoding:utf8 import?threading import?time def?func(name,?i):for?n?in?xrange(i):print?name,?ntime.sleep(1) t1?=?threading.Thread(target=func,?args=('聲音',3)) t2?=?threading.Thread(target=func,?args=('畫面',3)) t1.start() t2.start()[root@133?managehosts]#?python?threading02.py? 聲音?0 畫面?0 聲音?1 畫面?1 聲音?2 畫面?2如果添加一個t1.join(),則會先打印t1,然后再打印t2 t1.start() t1.join() t2.start()結(jié)果變?yōu)?#xff1a; [root@133?managehosts]#?python?threading02.py? 聲音?0 聲音?1 聲音?2 畫面?0 畫面?1 畫面?2


t1.setDaemon(True) 設(shè)置t1線程和主進程一起退出

[root@133?managehosts]#?vim?threading02.py?#!/usr/bin/env?python #encoding:utf8import?threading import?timedef?func(name,?i):for?n?in?xrange(i):print?name,?ntime.sleep(1)t1?=?threading.Thread(target=func,?args=('聲音',3)) t2?=?threading.Thread(target=func,?args=('畫面',3))t1.setDaemon(True)?#設(shè)置t1線程和主進程一起退出 t1.start()?????????#開啟t1線程,打印一次就會退出,因為主進程已經(jīng)退出 t2.setDaemon(True) t2.start()[root@133?managehosts]#?python?threading02.py? 聲音?0 畫面?0


互斥鎖

[root@133?managehosts]#?pwd /opt/python/managehosts [root@133?managehosts]#?cat?threading07.py #!/usr/bin/env?python import?threading import?time def?hello():for?i?in?xrange(5):h_lock.acquire()print?'hello',w_lock.release()def?world():for?i?in?xrange(5):w_lock.acquire()print?'world',time.ctime()h_lock.release()h_lock?=??threading.Lock() w_lock?=?threading.Lock()w_lock.acquire()t1?=?threading.Thread(target=hello,?args=()) t2?=?threading.Thread(target=world,?args=())t1.start() t2.start()[root@133?managehosts]#?python?threading07.py hello?world?Wed?Mar?29?11:51:59?2017 hello?world?Wed?Mar?29?11:51:59?2017 hello?world?Wed?Mar?29?11:51:59?2017 hello?world?Wed?Mar?29?11:51:59?2017 hello?world?Wed?Mar?29?11:51:59?2017#!/usr/bin/python import?thread import?timedef?hello():for?i?in?xrange(5):h_lock.acquire()print?'hello',w_lock.release()def?world():for?i?in?xrange(5):w_lock.acquire()print?'world'h_lock.release()lock.release()lock?=?thread.allocate_lock()? lock.acquire()???? h_lock?=?thread.allocate_lock() w_lock?=?thread.allocate_lock() w_lock.acquire() thread.start_new_thread(hello,?()) thread.start_new_thread(world,?())while?lock.locked():????pass


程序執(zhí)行開兩個線程,即hello和world。

執(zhí)行hello線程時,只有3步:

  • 先申請h_lock鎖,即h_lock.acquire()

  • 然后輸出hello,即print 'hello',

  • 最后釋放w_lock鎖,即w_lock.release()

  • 執(zhí)行world線程時也是3步:

  • 申請w_lock鎖,即w_lock.acquire()

  • 輸出world,即print 'world'

  • 釋放h_lock鎖,即h_lock.release()

  • 線程是同時執(zhí)行的,為什么hello和world會交替輸出,沒有先輸出world?

    在主線程里,申請了w_lock鎖,即26行的w_lock.acquire(),所以在world()函數(shù)里的w_lock.acquire()一直

    處于阻塞狀態(tài),意味著print 'world'這一行是不會執(zhí)行的,直到hello()函數(shù)里把w_lock釋放,即w_lock.release()

    所以在每個函數(shù)里都有釋放對方的鎖,這樣對方就把自己要輸出的內(nèi)容執(zhí)行了。

    最后world函數(shù)里的循環(huán)執(zhí)行完了,釋放lock這個鎖,這樣這個主進程也結(jié)束了。


    [root@133?managehosts]#?cat?threading08.py #!/usr/bin/env?pythonimport?threadingimport?timeclass?MyThread(threading.Thread):def?__init__(self):threading.Thread.__init__(self)def?run(self):global?countertime.sleep(1)mutex.acquire()?#獲得鎖counter?+=1print?"I?am?%s,?set?counter:%s"?%(self.name,counter)mutex.release()?#釋放鎖if?__name__?==?'__main__':counter?=?0mutex?=?threading.Lock()?#分配鎖for?i?in?xrange(300):t?=?MyThread()t.start()[root@133?managehosts]#?python?threading08.py I?am?Thread-1,?set?counter:1 I?am?Thread-2,?set?counter:2 I?am?Thread-3,?set?counter:3 I?am?Thread-4,?set?counter:4 I?am?Thread-5,?set?counter:5 I?am?Thread-6,?set?counter:6 I?am?Thread-7,?set?counter:7 I?am?Thread-8,?set?counter:8 I?am?Thread-9,?set?counter:9 I?am?Thread-10,?set?counter:10 I?am?Thread-11,?set?counter:11 I?am?Thread-12,?set?counter:12 I?am?Thread-13,?set?counter:13 I?am?Thread-14,?set?counter:14 I?am?Thread-15,?set?counter:15I?am?Thread-284,?set?counter:282 I?am?Thread-283,?set?counter:283 I?am?Thread-282,?set?counter:284 I?am?Thread-285,?set?counter:285 I?am?Thread-287,?set?counter:286 I?am?Thread-286,?set?counter:287 I?am?Thread-288,?set?counter:288 I?am?Thread-289,?set?counter:289 I?am?Thread-290,?set?counter:290 I?am?Thread-293,?set?counter:291 I?am?Thread-292,?set?counter:292 I?am?Thread-291,?set?counter:293 I?am?Thread-295,?set?counter:294 I?am?Thread-296,?set?counter:295 I?am?Thread-297,?set?counter:296 I?am?Thread-294,?set?counter:297 I?am?Thread-298,?set?counter:298 I?am?Thread-299,?set?counter:299 I?am?Thread-300,?set?counter:300


    轉(zhuǎn)載于:https://blog.51cto.com/daixuan/1896770

    總結(jié)

    以上是生活随笔為你收集整理的多线程介绍和多线程模块-lock-互斥锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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