• 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_video、play_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()在循环外,此时的thread为play_music,父进程只会等待play_music进程执行完就结束,而不会等待play_video(sleep时间较长)执行完才结束,所以才会有上面的结果

  • 相关阅读:
    selenium python Chromedriver 路径
    jenkins安装
    HTMLTestRunner 报告
    夜神模拟器/逍遥模拟器--apk安装应用
    安装adb
    一个网站如何测试
    自定义控件(优酷菜单)
    SVN图标含义总结
    UDP和TCP含义,区别
    GitHub远程库的操作(设置秘钥,将本地文件上传到远程库上,克隆远程库文件到本地,Git的分支与合并,设置标签)
  • 原文地址:https://www.cnblogs.com/shitaotao/p/7609983.html
Copyright © 2020-2023  润新知