通俗易懂的python多线程实例[后续]
之前讲了多线程的一篇博客,感觉讲的意犹未尽,其实,多线程非常有意思。因为我们在使用电脑的过程中无时无刻都在多进程和多线程。我们可以接着之前的例子继续讲。请先看我的上一篇博客。
从上面例子中发现线程的创建是颇为麻烦的,每创建一个线程都需要创建一个tx(t1、t2、...),如果创建的线程多时候这样极其不方便。下面对通过例子进行继续改进:
player.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date : 2016-02-26 15:52:16
# @Author : Aries (i@iw3c.com)
# @Link : http://iw3c.com
# @Version : $Id$
import threading
from time import ctime,sleep
def musics(name):
for i in range(2):
print "我正在听音乐:%s ,%s" % (name,ctime())
sleep(2)
def movies(name):
for i in range(2):
print "我正在看电影:%s ,%s" %(name,ctime())
sleep(5)
def player(name):
r = name.split('.')[1];
if 'mp3'==r:
musics(name)
else :
if 'mp4'==r:
movies(name)
else:
print "不好意思,这种格式我不认识"
lists=['似是故人来.mp3','突袭2.mp4']
threads = []
lens = len(lists)
#创建线程
for f in range(lens):
t = threading.Thread(target=player,args=(lists[f],))
threads.append(t)
if __name__ == '__main__':
for t in threads:
t.start()
for t in threads:
t.join()
print "完事儿了:%s" % ctime()
有趣的是我们又创建了一个player()函数,这个函数用于判断播放文件的类型。如果是mp3格式的,我们将调用music()函数,如果是mp4格式的我们调用move()函数。哪果两种格式都不是那么只能告诉用户你所提供有文件我播放不了。
然后,我们创建了一个list的文件列表,注意为文件加上后缀名。然后我们用len(list) 来计算list列表有多少个文件,这是为了帮助我们确定循环次数。
接着我们通过一个for循环,把list中的文件添加到线程中数组threads[]中。接着启动threads[]线程组,最后打印结束时间。
运行结果:
我正在听音乐:似是故人来.mp3 ,Fri Feb 26 16:08:04 2016
我正在看电影:突袭2.mp4 ,Fri Feb 26 16:08:04 2016
我正在听音乐:似是故人来.mp3 ,Fri Feb 26 16:08:06 2016
我正在看电影:突袭2.mp4 ,Fri Feb 26 16:08:09 2016
完事儿了:Fri Feb 26 16:08:14 2016
[Finished in 10.1s]
只要我们向lists中添加一个项,就会多创建一个线程。
好,下面我们来优化一下我们的代码。
new_player.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date : 2016-02-26 16:15:31
# @Author : Aries (i@iw3c.com)
# @Link : http://iw3c.com
# @Version : $Id$
import threading
from time import ctime,sleep
def player(name,sleepTime):
for i in range(2):
print "正在播放:%s ,%s" % (name,ctime())
sleep(sleepTime)
#字典:播放的文件与播放时长
lists = {'突袭2.mp4':5,'似是故人来.mp3':2,'天涯.mp3':3}
threads = []
lens = len(lists)
#n = name ,t = time
for n,t in lists.items():
t = threading.Thread(target=player,args=(n,t))
threads.append(t)
if __name__ == '__main__':
for t in threads:
t.start()
for t in threads:
t.join()
print "完事儿了:%s" % ctime()
首先创建字典lists ,用于定义要播放的文件及时长(秒),通过字典的items()方法来循环的取name和time,取到的这两个值用于创建线程。
接着创建player()函数,用于接收name和time,用于确定要播放的文件及时长。
最后是线程启动运行。运行结果:
正在播放:似是故人来.mp3 ,Fri Feb 26 16:22:15 2016
正在播放:天涯.mp3 ,Fri Feb 26 16:22:15 2016
正在播放:突袭2.mp4 ,Fri Feb 26 16:22:15 2016
正在播放:似是故人来.mp3 ,Fri Feb 26 16:22:17 2016
正在播放:天涯.mp3 ,Fri Feb 26 16:22:18 2016
正在播放:突袭2.mp4 ,Fri Feb 26 16:22:20 2016
完事儿了:Fri Feb 26 16:22:25 2016
[Finished in 10.1s]
再优化,我们要用自己的多线程类。
class.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date : 2016-02-26 16:24:26
# @Author : Aries (i@iw3c.com)
# @Link : http://iw3c.com
# @Version : $Id$
import threading
from time import ctime,sleep
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)
def player(name,sleepTime):
for i in range(2):
print "正在播放:%s ,%s" % (name,ctime())
sleep(sleepTime)
#字典:播放的文件与播放时长
lists = {'突袭2.mp4':5,'似是故人来.mp3':2,'天涯.mp3':3}
threads = []
lens = len(lists)
for n,t in lists.items():
t = MyThread(player,(n,t),player.__name__)
threads.append(t)
if __name__ == '__main__':
for t in threads:
t.start()
for t in threads:
t.join()
print "完事儿了:%s" % ctime()
MyThread(threading.Thread)
创建MyThread类,用于继承threading.Thread类。
__init__()
使用类的初始化方法对func、args、name等参数进行初始化。
apply()
apply(func [, args [, kwargs ]]) 函数用于当函数参数已经存在于一个元组或字典中时,间接地调用函数。args是一个包含将要提供给函数的按位置传递的参数的元组。如果省略了args,任何参数都不会被传递,kwargs是一个包含关键字参数的字典。
apply() 用法:
#不带参数的方法
>>> def say():
print 'say in'
>>> apply(say)
say in
#函数只带元组的参数
>>> def say(a,b):
print a,b
>>> apply(say,('hello','虫师'))
hello 虫师
#函数带关键字参数
>>> def say(a=1,b=2):
print a,b
>>> def haha(**kw):
apply(say,(),kw)
>>> haha(a='a',b='b')
a b
MyThread(play,(k,v),play.name)
由于MyThread类继承threading.Thread类,所以,我们可以使用MyThread类来创建线程。
运行结果:
正在播放:似是故人来.mp3 ,Fri Feb 26 16:29:41 2016
正在播放:天涯.mp3 ,Fri Feb 26 16:29:41 2016
正在播放:突袭2.mp4 ,Fri Feb 26 16:29:41 2016
正在播放:似是故人来.mp3 ,Fri Feb 26 16:29:43 2016
正在播放:天涯.mp3 ,Fri Feb 26 16:29:44 2016
正在播放:突袭2.mp4 ,Fri Feb 26 16:29:46 2016
完事儿了:Fri Feb 26 16:29:51 2016
[Finished in 10.1s]
所有的源码下载:http://pan.baidu.com/s/1pK5ziqR 密码: dce6