关于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
原文地址:https://www.cnblogs.com/rayshaw/p/9544807.html