python的多线程简单实例理解
来源:互联网 发布:火焰之地怎么去乎门人 编辑:程序博客网 时间:2024/05/20 17:26
一直以来对于线程的理解是比较模糊的,之前在用php的时候,由于php是不直接支持多线程,要用php_threads的扩展。最近由于公司项目的后台需要要到多线程,故学习了一下python的多线程,下面通过一个简单的例子说明一下。
在实际中,比如说要听音乐,看电影,做其他的任务,按照单例的话,只能是一件做接着一件做。如果每件事都是很耗时的,那就会影响效率。同理在编程的世界里。同样有很多的相似的逻辑业务。比如群发邮件,按照单例我们的程序就会用循环的方式,发完一个再发一个。但是,发邮件的这个过程却是要耗时的,这样样子的浪费多长的时间才能将大量的邮件发完。而且程序还有一个超时时间限制呢!(虽然可以设置为无限制)。可想而知,这样子的话,就会造成效率低,甚至发送不成功。
下面进入主题
1、看一个简单的例子
#!D:\Python43\python.exe# -*- coding: UTF-8 -*-from time import ctime,sleep#听音乐def music(musicname):for i in range(2) :print("我正在听音乐叫%s,时间是:%s" %(musicname,ctime()))sleep(5)#看电影def movie(moviename):for j in range(2) :print("我正在看电影叫%s,时间是:%s" %(moviename,ctime()))sleep(2)#主线程if __name__ =='__main__':music('当爱已成往事')movie('中华英雄')print('所有的娱乐结束,时间:%s' %ctime())
定义两个函数,分别做两个任务,听音乐和看电影
music函数就是任务打印出听音乐这句话(程序执行非常快,纳秒级),这个时间是在15:36:56.然后等待5s,再去打印出听音乐这句话,时间是15:37:01,然后再睡眠等待5s.所以在这个过程任务的用时为10s.
接着到执行movie函数,睡眠时间2s.这个过程用时就是4s
最后,执行主程序的结束。我的娱乐任务完成。所以在这个过程他是按照程序单线程一直执行的。效率非常低。
2、多线程引入(非阻塞)
</pre><pre name="code" class="html">def music(musicname):for i in range(2) :print("我正在听音乐叫%s,时间是:%s" %(musicname,ctime()))sleep(2)#看电影def movie(moviename):for j in range(2) :print("我正在看电影叫%s,时间是:%s" %(moviename,ctime()))sleep(2)threads=[]t1 = threading.Thread(target=music,args=(u'一路顺风',))threads.append(t1)t2 = threading.Thread(target=movie,args=(u'让子弹飞',))threads.append(t2)#主线程if __name__ =='__main__':#循环执行子线程for t in threads :#将父线程设置为了守护线程。#根据setDaemon()方法的含义,#父线程打印内容后便结束了,#不管子线程是否执行完毕了。t.setDaemon(True)t.start()print('所有的娱乐结束,时间:%s' %ctime())
可以看到,在执行主程序的时候,三个任务基本是同时完成,而且music和movie只执行一遍,任务还没全部完成。为什么呢?
首先过程是先把所有的子线程启动,即musi和movie,这里是两条不同路,接着同时执行主程序的
print('所有的娱乐结束,时间:%s'%ctime()),又是一条路
主程序结束,就会将退出,同时子线程也退出,不管你的任务有没有完成。所以music和movie在启动并打印出那句话时,在睡眠等待,那边的主程序也已经执行到打印操作,所以主程序就退出,同时也通知正在睡眠等待的子线程退出。所以他们只执行一次打印任务,就被迫退出。为什么会被迫退出呢?那与我们的逻辑业务不符合啊。不急,接着往下看。原因就在于这个setDaemon(True)就是将主进程设置为守护线程,根据setDaemon()方法的含义,父线程打印内容后便结束了,不管子线程是否执行完毕了,都退出
3、多线程(阻塞)
#!D:\Python43\python.exe# -*- coding: UTF-8 -*-from time import ctime,sleepimport threading#听音乐def music(musicname):for i in range(2) :print("我正在听音乐叫%s,时间是:%s" %(musicname,ctime()))sleep(5)#看电影def movie(moviename):for j in range(2) :print("我正在看电影叫%s,时间是:%s" %(moviename,ctime()))sleep(2)threads=[]t1 = threading.Thread(target=music,args=(u'一路顺风',))threads.append(t1)t2 = threading.Thread(target=movie,args=(u'让子弹飞',))threads.append(t2)#主线程if __name__ =='__main__':#循环执行子线程for t in threads :#将父线程设置为了守护线程。#根据setDaemon()方法的含义,#父线程打印内容后便结束了,#不管子线程是否执行完毕了。<span style="color:#ff0000;">#t.setDaemon(True)</span>t.start()<span style="color:#ff0000;">for t in threads :t.join()</span>print('所有的娱乐结束,时间:%s' %ctime())
将
t.setDaemon(True)</span>
屏蔽掉,同时再加入一个for循环
for t in threads :<span style="white-space:pre"></span>t.join()在执行主程序时,启动两个子线程,在15:18:09 同时执行一遍打印任务,两个子线程在睡眠等待中,时间到了,有同时个字执行一片打印任务。再睡眠等待2s后,再执行主程序的打印任务。
其实起作用的就是这个join()函数,这是一个阻塞函数,要子线程执行完了才能继续往下执行主程序(或其他程序)。
所以在for循环中,join()阻塞先等待第一个子线程结束后,在继续等待第二个子线程结束,如果第二个或者后面提前比前面的结束,则就会下一个join(),不需要等待(因为join()检查到该线程已经结束)。循环之后,就会往下执行主程序。所以整个过程所用的时间就是用时最长的任务的时间。所有的几乎是同时进行。
所以我们可以知道,setDaemon是与join()相对的。功能上基本是相反的
- python的多线程简单实例理解
- Python简单多线程实例
- 简单的多线程实例
- 简单的多线程理解
- python的多线程实例
- C#简单的多线程实例
- 简单的多线程实例C++
- python执行多线程的实例
- python执行多线程的实例
- 关于Python多线程的理解
- 简单的学习Python多线程
- python多线程的简单使用
- 怎样理解Servlet的单实例多线程
- 怎样理解Servlet的单实例多线程
- 怎样理解Servlet的单实例多线程
- 如何理解 servlet 的单实例多线程
- 怎样理解Servlet的单实例多线程
- 怎样理解Servlet的单实例多线程
- MFC多线程的简单实现
- Unity3d的ios插件开发
- Makefile的obj-y和obj-m语句
- Unity3d选择本地图片并加载
- Android之BroadcastReceiver的用法
- python的多线程简单实例理解
- JavaScript中的dom编程
- SSH:Hibernate框架(Hibernate集合Map关系映射)
- Mybatis逆向工程
- 性能分析工具Eclipse Memory Analyzer tool(MAT)
- 学习笔记之递归和分治思想
- 内存泄露入门之基础知识篇
- Java 选择排序 (Selection Sort)
- MySQLConnector/C++连接方式二