zoukankan      html  css  js  c++  java
  • 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 
    "%(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 
    "%(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 
    "%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 "%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 
    "%(video,ctime())
            sleep(1)
    
    
    def play_music(music):
        for i in range(2):
            print "i am playing music: %s at %s 
    "%(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 
    "%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 
    "%(video,ctime())
            sleep(5)
    
    
    def play_music(music):
        for i in range(2):
            print "i am playing music: %s at %s 
    "%(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 
    "%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时间较长)执行完才结束,所以才会有上面的结果

  • 相关阅读:
    洛谷 1850 NOIP2016提高组 换教室
    2018牛客多校第三场 C.Shuffle Cards
    2018牛客多校第一场 B.Symmetric Matrix
    2018牛客多校第一场 A.Monotonic Matrix
    2018牛客多校第一场 D.Two Graphs
    2018宁夏邀请赛L Continuous Intervals
    2018宁夏邀请赛K Vertex Covers
    BZOJ
    HDU
    ACM International Collegiate Programming Contest, Egyptian Collegiate Programming Contest (ECPC 2015)
  • 原文地址:https://www.cnblogs.com/wc554303896/p/7083023.html
Copyright © 2011-2022 走看看