多线程介绍和多线程模块-lock-互斥锁
多線程介紹和多線程模塊
線程的特點:
線程的生命周期
開始
運行
結(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 畫面?2LockType對象方法
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é)束
如果添加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 completet1.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é)束了。
轉(zhuǎn)載于:https://blog.51cto.com/daixuan/1896770
總結(jié)
以上是生活随笔為你收集整理的多线程介绍和多线程模块-lock-互斥锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转 php include
- 下一篇: 全局照明算法基础——从辐射亮度到渲染方程