Selenium 2自动化测试实战41(多线程技术)

多线程技术python

python经过两个标准库thread和threading提供对线程的支持。thread提供了低级别的,原始的线程以及一个简单的锁。threading基于Java的线程模型设计。数组

1.threading模块
应该避免使用thread模块,缘由是它不支持守护线程。当主线程退出时,全部的子线程无论他们是否还在工做,都会被强行退出。有时候并不但愿出现此种行为,所以就引入了守护线程的概念。threading模块支持守护线程,因此,咱们直接使用threading来改进上述的例子。多线程

#threads.py
#coding:utf-8 from time import sleep,ctime import threading #听音乐任务 def music(func,loop): for i in range(loop): print('i was listening to %s! %s' % (func,ctime())) sleep(2) #看电影任务 def movies(func,loop): for i in range(loop): print('i was watch the %s!%s' %(func,ctime())) sleep(5) #建立线程数组 threads=[] #建立线程t1,并添加到线程数组 t1=threading.Thread(target=music,args=(u'爱情买卖',2)) threads.append(t1) #建立线程t2,并添加到线程数组 t2=threading.Thread(target=movies,args=(u'阿凡达',2)) threads.append(t2) if __name__=="__main__": #启动线程 for t in threads: t.start() #守护线程 for t in threads: t.join() print ('all end %s' %ctime())

执行以后,结果以下图所示:app

-import threading:引入线程模块
-threads=[]:建立线程数组,用于装载线程。
-threading.Thread():经过调用threading模块的Thread()方法来建立线程。函数

经过for循环遍历threads数组中所装载的线程,start()开始线程活动,join()等待线程终止。若是不使用join()方法对每一个线程作等待终止,那么在线程运行的过程当中可能会去执行最后的打印“all end…”
代码分析:
从上面的运行结果能够看出,两个子线程(music/movie)同时启动于46分09秒,直到全部线程结束于46分19秒,总耗时10秒,movie的两次电影循环共须要10秒,music的歌曲循环须要4秒,从执行结果看出两个线程达到了并行工做。oop

 

2.优化线程的建立
上述例子中,每建立一个线程都须要建立一个t(t1,t2,……),当建立的线程较多时,这样不方便,所以下面例子将做出改进。优化

#player.py
#coding:utf-8 from time import sleep,ctime import threading #建立超级播放器 def super_player(file_,time): for i in range(2): print 'Start playing:%s! %s' %(file_,ctime()) sleep(time) #播放的文件与播放时长 lists={u'爱情买卖.mp3':3,u'阿凡达.mp4':5,u'我和你.mp3':4} threads=[] files=range(len(lists)) #建立线程 for file_,time in lists.items(): t=threading.Thread(target=super_player,args=(file_,time)) threads.append(t) if __name__=="__main__": #启动线程 for t in files: threads[t].start() for t in files: threads[t].join() print 'all end"%s' %ctime()

执行以后,结果以下图所示:spa

 

 

此例中,对播放器的功能也作了加强,首先,建立了一个super_player()函数,这个函数能够接收播放文件和播放时长,能够播听任何文件。线程

而后,咱们建立了一个lists字典用于存放播放文件名与时长,经过for循环读取字典,并调用super_player()函数建立字典,接着将建立的字典都追加到threads数组中。设计

 

3.建立线程类
除直接使用python所提供的线程类外,还能够根据需求自定义本身的线程类。

#mythread.py
#coding:utf-8 from time import sleep,ctime import threading #建立线程类 class MyThreads(threading.Thread): def __init__(self,func,args,name=''): threading.Thread.__init__(self) self.func=func self.args=args self.name=name def run(self): self.func(*self.args) def super_play(file_,time): for i in range(2): print('Start playing:%s! %s' %(file_,ctime())) sleep(time) lists={u'爱情买卖.mp3':3,u'阿凡达.mp4':5,u'我和你.mp3':4} threads=[] files=range(len(lists)) for file_,time in lists.items(): t=MyThreads(super_play,(file_,time),super_play.__name__) threads.append(t) if __name__=='__main__': #启动线程 for i in files: threads[i].start() for i in files: threads[i].join() print'all end:%s' %ctime()

执行以后,结果以下图所示:

 

 

MyThreads(threading.Thread)
建立MyThread类,用于继承threading.Thread类
__init__()类的初始化方法对func、args、name等参数进行初始化。


在python2中,apply(func[,args[,kwargs]])函数的做用是当函数参数已经存在于一个元组或字典中,apply()间接地调用函数。args是一个包含将要提供给函数的按位置传递的参数的元组。若是省略了args,则任何参数都不会被传递,kwargs是一个包含关键字参数的字典。

Python3中已经再也不支持apply()函数,因此将
-apply(self.func,self.args)
修改成
Self.func(*self.args)

最后,线程的建立与启动与前面的例子相同,惟一的区别是建立线程使用的是MyThreads类,线程的入参形式也有所改变。

相关文章
相关标签/搜索