单线程
比如两件事,要相继执行,而不是一起执行
'''学习一下单线程和多线程的问题'''
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