Python的多線程編程


提到多線程,很多人就會望而卻步,本文將由淺入深地帶你攻克python多線程編程,並防止你跳入深坑,

首先看一段簡單的代碼:

 1 from time import ctime,sleep
 2 def play_video(video):
 3     for i in range(2):
 4         print "i am playing video: %s at %s"%(video,ctime())
 5         sleep(4)
 6 
 7 
 8 def play_music(music):
 9     for i in range(2):
10         print "i am playing music: %s at %s"%(music,ctime())
11         sleep(2)
12 
13 
14 if __name__=="__main__":
15     
16     play_video("speed_and_crazy")
17     play_music("chengdu")
18 
19     print "all are over at %s"%ctime()
20                 
21     

執行結果:

C:\Python27>python mui_thread.py
i am playing video: speed_and_crazy at Mon Jun 26 23:01:59 2017
i am playing video: speed_and_crazy at Mon Jun 26 23:02:03 2017
i am playing music: chengdu at Mon Jun 26 23:02:07 2017
i am playing music: chengdu at Mon Jun 26 23:02:09 2017
all are over at Mon Jun 26 23:02:11 2017

隨着人們對多任務的要求,同時為了充分利用cpu資源,多線程編程不可避免,那么我們如何利用python去實現play_video和play_music

兩個任務同時運行呢?

 1 from time import ctime,sleep
 2 import threading
 3 def play_video(video):
 4     for i in range(2):
 5         print "i am playing video: %s at %s \n"%(video,ctime())
 6         sleep(5)
 7 
 8 
 9 def play_music(music):
10     for i in range(2):
11         print "i am playing music: %s at %s \n"%(music,ctime())
12         sleep(1)
13 
14 threads=[]
15 
16 thread1=threading.Thread(target=play_video,args=("speed_and_crazy",))
17 
18 threads.append(thread1)
19 
20 thread2=threading.Thread(target=play_music,args=("chengdu",))
21 
22 threads.append(thread2)
23 
24 
25 
26 if __name__=="__main__":
27 
28     for thread in threads:
29         thread.setDaemon(True) #將線程聲明為守護線程,必須在start()方法調用之前,如果不設置為守護線程,程序會被無限掛起
30         thread.start()
31 
32     print "all are over at %s \n"%ctime()
33                 
34     

測試結果:

C:\Python27>python mui_thread.py
i am playing video: speed_and_crazy at Mon Jun 26 23:18:52 2017
all are over at Mon Jun 26 23:18:52 2017
i am playing music: chengdu at Mon Jun 26 23:18:52 2017  #從打印的時間可知,play_video、play_music和父進程幾乎同時運行

從結果看,與我們最初的目標相差甚遠,怎么沒有按照順序執行,為什么每個函數都只有一條日記輸出?

那是因為子線程(play_videoplay_music)和主線程print "all are over at %s \n"%ctime()都是同一時間啟動,但由於主線程已經運行結束,所以導致子線程也同時終止,在這種條件下,我們如何保證子進程都能夠執行完畢呢?

增加thread.join()並 放在循環外

from time import ctime,sleep
import threading
def play_video(video):
    for i in range(2):
        print "i am playing video: %s at %s \n"%(video,ctime())
        sleep(1)


def play_music(music):
    for i in range(2):
        print "i am playing music: %s at %s \n"%(music,ctime())
        sleep(5)

threads=[]

thread1=threading.Thread(target=play_video,args=("speed_and_crazy",))

threads.append(thread1)

thread2=threading.Thread(target=play_music,args=("chengdu",))

threads.append(thread2)



if __name__=="__main__":

    for thread in threads:
        thread.setDaemon(True)
        thread.start()
    thread.join()  #加在循環外,
    print "all are over at %s \n"%ctime()
                
    

運行結果:

 1 C:\Python27>python mui_thread.py
 2 i am playing video: speed_and_crazy at Mon Jun 26 23:32:21 2017
 3 i am playing music: chengdu at Mon Jun 26 23:32:21 2017
 4 
 5 
 6 i am playing video: speed_and_crazy at Mon Jun 26 23:32:22 2017
 7 
 8 i am playing music: chengdu at Mon Jun 26 23:32:26 2017
 9 
10 all are over at Mon Jun 26 23:32:31 2017
thread.join()的作用是主線程必須等待子線程都執行完了才能結束,play_video、play_music幾乎同時執行
但是如果改變play_video、play_music里面的sleep的時長,即是下面的代碼:
from time import ctime,sleep
import threading
def play_video(video):
    for i in range(2):
        print "i am playing video: %s at %s \n"%(video,ctime())
        sleep(5)


def play_music(music):
    for i in range(2):
        print "i am playing music: %s at %s \n"%(music,ctime())
        sleep(1)

threads=[]

thread1=threading.Thread(target=play_video,args=("speed_and_crazy",))

threads.append(thread1)

thread2=threading.Thread(target=play_music,args=("chengdu",))

threads.append(thread2)



if __name__=="__main__":

    for thread in threads:
        thread.setDaemon(True)
        thread.start()
    thread.join()
    print "all are over at %s \n"%ctime()
                
    

此時運行結果:

C:\Python27>python mui_thread.py
i am playing video: speed_and_crazy at Mon Jun 26 23:44:13 2017
i am playing music: chengdu at Mon Jun 26 23:44:13 2017


i am playing music: chengdu at Mon Jun 26 23:44:14 2017

all are over at Mon Jun 26 23:44:15 2017

我們看到play_video還有一條log沒有打印出來,原因是thread.join()在循環外,此時的threadplay_music,父進程只會等待play_music進程執行完就結束,而不會等待play_video(sleep時間較長)執行完才結束,所以才會有上面的結果

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM