thread

from time import sleep, ctime
import thread

loops = [4, 2]



def loop(nloop, nsec, lock):
print 'start loop', nloop, 'at:', ctime()
sleep(nsec)
print 'loop', nloop, 'done at:', ctime()
lock.release()

def main():
print 'starting at:', ctime()
locks = []
nloops = range(len(loops))

for i in nloops:
lock = thread.allocate_lock() #鎖列表
lock.acquire()#獲得鎖
locks.append(lock)

for i in nloops:
thread.start_new_thread(loop, (i, loops[i], locks[i]))

for i in nloops:
while locks[i].locked():pass

print 'all done at:',ctime()


if __name__ == '__main__':
main()

逐行解釋:

1-6 行
在 Unix 啓動信息行後面,我們導入了 thread 模塊和 time 模塊裏我們早已熟悉的幾個函數。我
們不再在函數裏寫死要等 4 秒和 2 秒,而是使用一個 loop()函數,把這些常量放在一個列表 loops
裏。

8-12 行
loop()函數替換了我們之前的那幾個 loop*()函數。在 loop()函數裏,增加了一些鎖的操作。
一個很明顯的改變是,我們現在要在函數中記錄下循環的號碼和要睡眠的時間。最後一個不一樣的
地方就是那個鎖了。每個線程都會被分配一個事先已經獲得的鎖,在 sleep()的時間到了之後就釋放
相應的鎖以通知主線程,這個線程已經結束了。

14-34 行
主要的工作在包含三個循環的 main()函數中完成。我們先調用 thread.allocate_lock()函數創
建一個鎖的列表,並分別調用各個鎖的 acquire()函數獲得鎖。獲得鎖表示“把鎖鎖上”。鎖上後,
我們就把鎖放到鎖列表 locks 中。下一個循環創建線程,每個線程都用各自的循環號,睡眠時間和
鎖爲參數去調用 loop()函數。爲什麼我們不在創建鎖的循環裏創建線程呢?有以下幾個原因:(1) 我
們想到實現線程的同步,所以要讓“所有的馬同時衝出柵欄”。(2) 獲取鎖要花一些時間,如果你的
線程退出得“太快”,可能會導致還沒有獲得鎖,線程就已經結束了的情況。
在線程結束的時候,線程要自己去做解鎖操作。最後一個循環只是坐在那一直等(達到暫停主
線程的目的),直到兩個鎖都被解鎖爲止才繼續運行。由於我們順序檢查每一個鎖,所以我們可能會
要長時間地等待運行時間長且放在前面的線程,當這些線程的鎖釋放之後,後面的鎖可能早就釋放
了(表示對應的線程已經運行完了)。結果主線程只能毫不停歇地完成對後面這些鎖的檢查。最後兩
行代碼的意思你應該已經知道了,就是只有在我們直接運行這個腳本時,才運行 main()函數。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章