zoukankan      html  css  js  c++  java
  • 关于python的单线程和多线程

    单线程

    比如两件事,要相继执行,而不是一起执行

    
    '''学习一下单线程和多线程的问题'''
    
    from time import ctime,sleep
    '''单线程'''
    print('单线程开始:')
    def music_single(name):
        for i in range(2):
            print('i was listening to music %s. %s' %(name,ctime()))
            sleep(1)
    def move_single(name):
        for i in range(2):
            print('i was at the movies %s! %s' %(name,ctime()))
            sleep(5)
    if __name__=="__main__":
        music_single(u'夜空中最亮的星')
        move_single(u'谍影重重')
        print('all over %s' %ctime())
    
    

    输出结果:

    单线程开始:
    i was listening to music 夜空中最亮的星. Mon Aug 27 21:24:03 2018
    i was listening to music 夜空中最亮的星. Mon Aug 27 21:24:04 2018
    i was at the movies 谍影重重! Mon Aug 27 21:24:05 2018
    i was at the movies 谍影重重! Mon Aug 27 21:24:10 2018
    all over Mon Aug 27 21:24:15 2018
    

    多线程

    即边听歌边看电影,python中有thread和threading用来实现多线程,在这里使用threading。

    '''多线程'''
    print('****************')
    print('多线程开始:')
    from time import ctime,sleep
    import threading
    
    def music_mutil(name):
        for i in range(2):
            print('i was listening to music %s. %s' %(name,ctime()))
            sleep(1)
    def move_mutil(name):
        for i in range(2):
            print('i was at the movies %s! %s' %(name,ctime()))
            sleep(5)
    
    threads=[]
    t1=threading.Thread(target=music_mutil,args=(u'夜空中最亮的星',)) # 创建线程t1
    threads.append(t1)
    t2=threading.Thread(target=move_mutil,args=(u'谍影重重',)) # 创建线程t2
    threads.append(t2)
    
    if __name__=='__main__':
        for t in threads: # 遍历线程数组
            t.setDaemon(True) # 将线程声明为守护线程,必须在start()之前设置,如果不设置为守护线程,那么程序会被无限挂起。
            t.start() # 开始线程    
        t.join()
        print('all over %s' %ctime())
    

    输出结果:

    
    ****************
    多线程开始:
    i was listening to music 夜空中最亮的星. Mon Aug 27 21:24:15 2018
    i was at the movies 谍影重重! Mon Aug 27 21:24:15 2018
    i was listening to music 夜空中最亮的星. Mon Aug 27 21:24:16 2018
    i was at the movies 谍影重重! Mon Aug 27 21:24:20 2018
    all over Mon Aug 27 21:24:25 2018
    

    注意:
    倘若没有join()语句,那么输出结果为

    ****************
    多线程开始:
    i was listening to music 夜空中最亮的星. Mon Aug 27 21:27:29 2018
    i was at the movies 谍影重重! Mon Aug 27 21:27:29 2018
    all over Mon Aug 27 21:27:29 2018
    

    分析:
    以上,从运行结果看,子线程(music_mutil,move_mutil)和主线程(print(all over %s) %ctime())一起启动,但是主线程结束导致子线程也终止。在这里可以在主线程前面加上t.join(),其作用是在子线程完成运行之前,子线程的父线程将一直被阻塞。注意,join()的位置是在for循环外的,也就是说必须等待for循环里的两个进程都结束后,才去执行主进程。

    多线程进阶

    重写一下代码,写一个player,根据文件类型来选择操作。

    from time import ctime,sleep
    import threading
    
    def music(name):
        for i in range(2):
            print('start playing %s. %s' %(name,ctime()))
            sleep(2)
    
    def move(name):
        for i in range(2):
            print('start playing %s. %s' %(name,ctime()))
            sleep(5)
    
    def player(func):
        rc=func.split('.')[1]
        if rc=='mp3':
            music(func)
        else:
            if rc=='mp4':
                move(func)
            else:
                print('error type of file!')
    
    alist=['夜空中最亮的星.mp3','谍影重重.mp4']
    length=len(alist)
    threads=[]
    # 创建线程
    for i in range(length):
        t=threading.Thread(target=player,args=(alist[i],))
        threads.append(t)
    if __name__=='__main__':
        # 启动线程
        for i in range(length):
            threads[i].start()
        for i in range(length):
            threads[i].join()
    
        # 主线程
        print('all over at %s' %(ctime()))
    
    

    输出:

    start playing 夜空中最亮的星.mp3. Mon Aug 27 21:52:50 2018
    start playing 谍影重重.mp4. Mon Aug 27 21:52:50 2018
    start playing 夜空中最亮的星.mp3. Mon Aug 27 21:52:52 2018
    start playing 谍影重重.mp4. Mon Aug 27 21:52:55 2018
    all over at Mon Aug 27 21:53:00 2018
    

    继续修改:

    from time import ctime,sleep
    import threading
    
    def super_player(name,time0):
        for i in range(2):
            print('now we are playing %s. %s' %(name,ctime()))
            sleep(time0)
    # 
    alist={'飞鸟.mp3':3,'阿凡达.mp4':4,'我和你.mp3':4}
    
    threads=[]
    files=range(len(alist))
    
    # 创建线程
    for file,time in alist.items():
        t=threading.Thread(target=super_player,args=(file,time))
        threads.append(t)
    
    if __name__=='__main__':
        # 启动线程
        for i in files:
            threads[i].start()
        for i in files:
            threads[i].join()
        # 主线程
        print('end: %s' %ctime())
    

    输出:

    now we are playing 飞鸟.mp3. Mon Aug 27 21:57:02 2018
    now we are playing 阿凡达.mp4. Mon Aug 27 21:57:02 2018
    now we are playing 我和你.mp3. Mon Aug 27 21:57:02 2018
    now we are playing 飞鸟.mp3. Mon Aug 27 21:57:05 2018
    now we are playing 我和你.mp3. Mon Aug 27 21:57:06 2018
    now we are playing 阿凡达.mp4. Mon Aug 27 21:57:06 2018
    end: Mon Aug 27 21:57:10 2018
    

    继续创建:

    '''创建自己的多线程类'''
    
    #coding=utf-8
    import threading
    from time import sleep,ctime
    
    class MyThread(threading.Thread):
        def __init__(self,func,args,name=''):
            threading.Thread.__init__(self)
            self.name=name
            self.func=func
            self.args=args
        def run(self):
            # apply(self.func,self.args) # python2的用法
            self.func(*self.args) # python3没有了apply()的全局用法。用self.func(*self.args)。
    
    def super_play(file,time):
        for i in range(2):
            print('start playing: %s! %s' %(file,ctime()))
            sleep(time)
    
    alist={'红日.mp3':3,'阿凡达.mp4':5}
    
    # 创建线程
    threads=[]
    files=range(len(alist))
    
    for k,v in alist.items():
        t=MyThread(super_play,(k,v),super_play.__name__)
        threads.append(t)
    
    if __name__=='__main__':
        # 启动线程
        for i in files:
            threads[i].start()
        for i in files:
            threads[i].join()
        # 主线程
        print('end: %s' %ctime())
    

    输出:

    start playing: 红日.mp3! Mon Aug 27 21:58:48 2018
    start playing: 阿凡达.mp4! Mon Aug 27 21:58:48 2018
    start playing: 红日.mp3! Mon Aug 27 21:58:51 2018
    start playing: 阿凡达.mp4! Mon Aug 27 21:58:53 2018
    end: Mon Aug 27 21:58:58 2018
    
  • 相关阅读:
    OSI安全体系结构
    PHP 二维数组根据相同的值进行合并
    Java实现 LeetCode 17 电话号码的字母组合
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 14 最长公共前缀
  • 原文地址:https://www.cnblogs.com/rayshaw/p/9544807.html
Copyright © 2011-2022 走看看