Python多线程学习

来源:互联网 发布:淘宝 饰品店 利润 编辑:程序博客网 时间:2024/04/28 21:44

Python多线程学习

首先了解一下单线程,在啊很多年前的MS -DOS时代,操作系统处理问题都是单任务的,我想做听音乐和看电影两件事儿,那么一定要先排一下顺序。

from time import ctime,sleepdef music():    for i in range(2):        print "I was listening to music. %s" %ctime()        sleep(1)def move():    for i in range(2):        print "I was at the movies! %s" %ctime()        sleep(5)if __name__ == '__main__':    music()    move()    print "all over %s" %ctime()

我们先听了一首音乐,通过for循环来控制音乐的播放了两次,每首音乐播放需要1秒钟,sleep()来控制音乐播放的时长。接着我们又看了一场电影,每一场电影需要5秒钟,因为太好看了,所以我也通过for循环看两遍。在整个休闲娱乐活动结束后,我通过
print “all over %s” %ctime()
看了一下当前时间,差不多该睡觉了。
运行结果:
这里写图片描述

其实,music()和move()更应该被看作是音乐和视频播放器,至于要播放什么歌曲和视频应该由我们使用时决定。所以,我们对上面代码做了改造:

#coding=utf-8from time import ctime,sleepdef music(func):    for i in range(2):        print "I was listening to %s. %s" %(func,ctime())        sleep(1)def move(func):    for i in range(2):        print "I was at the %s! %s" %(func,ctime())        sleep(5)if __name__ == '__main__':    music(u'今生你作伴')    move(u'阿凡达')    print "all over %s" %ctime()

对music()和move()进行了传参处理。体验中国经典歌曲和欧美大片文化。
运行结果:
这里写图片描述

下面我们重点了解多线程是怎么回事,科技在发展,时代在进步,我们的CPU也越来越快,CPU抱怨,P大点事儿占了我一定时间,其实我同时干多个活都没有问题的;于是,操作系统就进入了多任务时代。我们听着音乐吃着火锅的不再是梦想。

python提供了两个模块来实现多线程thread 和threading ,thread 有一些缺点,在threading 得到了弥补,为了不浪费你和时间,所以我们直接学习threading 就可以了。

继续对上面的例子进行改造,引入threadring来同时播放音乐和视频:

#coding=utf-8import threadingfrom time import ctime,sleepdef music(func):    for i in range(2):        print "I was listening to %s. %s" %(func,ctime())        sleep(1)def move(func):    for i in range(2):        print "I was at the %s! %s" %(func,ctime())        sleep(5)threads = []t1 = threading.Thread(target=music,args=(u'爱情买卖',))threads.append(t1)t2 = threading.Thread(target=move,args=(u'阿凡达',))threads.append(t2)if __name__ == '__main__':    for t in threads:        t.setDaemon(True)        t.start()    print "all over %s" %ctime()
import threading

首先导入threading模块,这是使用多线程的前提

threads = []t1 = threading.Thread(target=music,args=(u'今生你作伴',))threads.append(t1)

创建了threads数组,创建线程t1,使用threading.Thread()方法,在这个方法中调用music方法target=music,args方法对music进行传参。 把创建好的线程t1装到threads数组中。

接着以同样的方式创建线程t2,并把t2也装到threads数组。

for t in threads:  t.setDaemon(True)  t.start()

最后通过for循环遍历数组。(数组被装载了t1和t2两个线程)

setDaemon()

setDaemon(True)将线程声明为守护线程,必须在start() 方法调用之前设置,如果不设置为守护线程程序会被无限挂起。子线程启动后,父线程也继续执行下去,当父线程执行完最后一条语句print “all over %s” %ctime()后,没有等待子线程,直接就退出了,同时子线程也一同结束。

start()

开始线程活动

运行结果如下:
这里写图片描述

从执行结果来看:
子线程(muisc 、move )和主线程(print “all over %s” %ctime())都是同一时间启动,但由于主线程执行完结束,所以导致子线程也终止。

对上述程序稍作修改:

if __name__ == '__main__':    for t in threads:        t.setDaemon(True)        t.start()    t.join()    print "all over %s" %ctime()

运行结果如下:
这里写图片描述

我们只对上面的程序加了个join()方法,用于等待线程终止。join()的作用是,在子线程完成运行之前,这个子线程的父线程将一直被阻塞。
  
注意: join()方法的位置是在for循环外的,也就是说必须等待for循环里的两个进程都结束后,才去执行主进程。

从上面例子中发现线程的创建是颇为麻烦的,每创建一个线程都需要创建一个tx(t1、t2、…),如果创建的线程多时候这样极其不方便。下面对通过例子进行继续改进:

#coding=utf-8from time import sleep, ctimeimport threadingdef super_player(file,time):    for i in range(2):        print 'Start playing: %s! %s' %(file,ctime())        sleep(time)#播放的文件与播放时长list = {'今生你作伴.mp3':3,'阿凡达.mp4':5,'我和你.mp3':4}threads = []files = range(len(list))#创建线程for file,time in list.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()

首先创建字典list ,用于定义要播放的文件及时长(秒),通过字典的items()方法来循环的取file和time,取到的这两个值用于创建线程。

接着创建super_player()函数,用于接收file和time,用于确定要播放的文件及时长。

最后是线程启动运行。运行结果:
这里写图片描述

创建自己的多线程类

#coding=utf-8import threadingfrom time import sleep, ctimeclass 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 super_play(file,time):    for i in range(2):        print 'Start playing: %s! %s' %(file,ctime())        sleep(time)list = {'今生你作伴.mp3':3,'阿凡达.mp4':5}#创建线程threads = []files = range(len(list))for k,v in list.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()

运行结果如下:
这里写图片描述

深入学习才会有意想不到的收获,继续努力,加油~

0 0
原创粉丝点击