join和 Daemon守护线程
一、前言
一个程序至少有一个主线程,主线程启动子线程后,它们之间并没有隶属关系。主线程和子线程执行是并行的,相互独立。主线程执行完毕后默认不等子线程执行结束就接着往下走了,如果有其他程序就会运行另外的程序,如果没有就等待子线程执行完成后结束程序。
结果:
二、join 等待子线程完成
如果在线程实例后加上join默认主线程是阻塞的,主线程会等待该子线程运行完成后在结束。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
# -*- coding: UTF-8 -*-import threadingimport timeimport randomclass MyThread(threading.Thread): def __init__(self, n): super(MyThread, self).__init__() self.n = n def run(self): print('task %s is operating' % self.n) t_time = random.randint(1, 8) time.sleep(t_time) print(self.getName(), 'finished', 'I sleep %d seconds' % t_time)if __name__ == '__main__': start_time = time.time() for i in range(5): t = MyThread(i) t.start() t.join() # 添加join,阻塞主线程 print('main thread finished.') print('cost: %s' % (time.time() - start_time))# 注# 如果对每个线程都加join,那么并发就没有了,实际上线程都是串行的# 前一个线程执行完了,才会执行下一个线程# 主线程最后运行完毕 |
结果:
2.1 计算并发运行时间
如果不想计算出总的运行时间,而是所有线程的并发运行时间呢?就像上例中的那样,最长运行时间是8秒,那么所有线程都能在8秒内全部运行完毕。
把t.join()单独移到for循环外面是不行的,因为这样并发运行总会在最后一个线程出阻塞。如下:
结果:
正确的方法,定义一个空列表,获取所以的线程实例,for 循环阻塞所有的线程实例
结果,事实上也符合我们刚才的推论,运行时间最长的线程所消耗的时间,就是总的并发时间
总结:主线程创建一个子线程后,如果子线程调用join()方法,主线程会在调用的地方等待,直到该子线程运行完成才会接着往下执行。
三、守护线程setDaemon
setDaemon()方法:在主线程中创建子线程,该子线程调用setDaemon方法后成为主线程的守护线程。这种情况下如果主线程执行结束,那么不管子线程是否完成,一并和主线程退出。这里基本和join()方法相反。此外,还有个要特别注意的:必须在start() 方法调用之前设置,如果不设置为守护线程,程序会被无限挂起。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
# -*- coding: UTF-8 -*-import threadingimport timeimport randomclass MyThread(threading.Thread): def __init__(self, n): super(MyThread, self).__init__() self.n = n def run(self): print('task %s is operating' % self.n) t_time = random.randint(1, 8) time.sleep(t_time) print(self.getName(), 'finished', 'I sleep %d seconds' % t_time)if __name__ == '__main__': start_time = time.time() for i in range(5): t = MyThread(i) t.setDaemon(True) t.start() print('main thread finished.', threading.current_thread(), threading.active_count()) print('cost: %s' % (time.time() - start_time)) |
注:threading.current_thread()查看当前运行的线程
threading.active_count() 查看活跃线程数
线程数 = 主线程 + 子线程数
结果:
|
1
2
3
4
5
6
7
8
9
10
11
|
task 0 is operatingtask 1 is operatingtask 2 is operatingtask 3 is operatingtask 4 is operatingmain thread finished. <_MainThread(MainThread, started 8656)> 6cost: 0.0009999275207519531Process finished with exit code 0# 很显然把子线程设置为主线程的守护线程后,主线程一旦结束,程序就执行退出运行,不会再等待子线程运行。 |
注:如果程序中有其他非守护线程时,还是会等待非守护线程运行完毕,程序才会结束。
join和 Daemon守护线程的更多相关文章
- (4)进程---daemon守护线程和join阻塞
join ()方法:主线程A中,创建了子线程B,并且在主线程A中调用了B.join(),那么,主线程A会在调用的地方等待,直到子线程B完成操作后,才可以接着往下执行,那么在调用这个线程时可以使用被调用 ...
- python网络编程--线程join和Daemon(守护进程)
一:什么情况下使用join join([timeout])调用join函数会使得主调线程阻塞,直到被调用线程运行结束或超时. 参数timeout是一个数值类型,用来表示超时时间,如果未提供该参数,那么 ...
- Python多进程的Join和daemon(守护)的用法
join和daemon 下面仅以多进程为例: 知识点一: 当一个进程启动之后,会默认产生一个主线程,因为线程是程序执行流的最小单元,当设置多线程时,主线程会创建多个子线程,在python中,默认情况下 ...
- java 多线程:Thread类常用方法:setPriority优先级、interrupt中断标记、suspend暂停与唤醒resume(已过时);daemon守护线程
常用方法: boolean isAlive() 测试此线程是否存活. boolean isDaemon() 测试此线程是否为守护程序线程. static void sleep?(long millis ...
- Java Daemon 守护线程
Java中可以通过Thread或ThreadGroup的setDaemon方法将线程设置为守护线程 当所有非守护线程退出后 守护线程将被杀死不在运行 .Net中可以通过设置IsBackground属性 ...
- 进程Process之join、daemon(守护)、terminate(关闭)、multiprocessing之锁、信号量和事件
一.Process 参数介绍: 1 group参数未使用,值始终为None 2 target表示调用对象,即子进程要执行的任务 3 args表示调用对象的位置参数元组,args=(1,2,'a',) ...
- 进程Process之join、daemon(守护)、terminate(关闭)
一.Process 参数介绍: 1 group参数未使用,值始终为None 2 target表示调用对象,即子进程要执行的任务 3 args表示调用对象的位置参数元组,args=(1,2,'a',) ...
- Daemon 守护线程(27-11)
t2.setDaemon(True)不再等待里面的sleep(5). 当设成setDaemon(True)这个线程就不等了. 例子一: import threadingfrom time import ...
- Java中的守护线程和非守护线程(转载)
<什么是守护线程,什么是非守护线程> Java有两种Thread:"守护线程Daemon"(守护线程)与"用户线程User"(非守护线程). 用户线 ...
随机推荐
- 开启session
在index.php中开启 session_start();
- 矩阵 matrix
传送门 注意这题时限是2s [问题描述] 有一个n × m的矩阵,你从左上角走到右下角,只能向下和向右走. 每个点上有一个重量v i,j 价值w i,j 的物品,你有一个容量为S的背包,经过一个点你可 ...
- 零值比较--BOOL,int,float,指针变量与零值比较的if语句
这是程序员面试的一道常见题,也是个C++基础问题.若只在大学里看过几本基础的编程入门书,看见这道题可能会觉得奇怪,不就是和0比较吗,直接拿出来比就是了,其实非也.下文引自google搜索结果,出处不详 ...
- QByteArray储存二进制数据(包括结构体,自定义QT对象)
因为利用QByteArray可以很方便的利用其API对内存数据进行访问和修改, 构建数据库blob字段时必不可少; 那如何向blob内写入自定义的结构体和类 //自定义person结构体 typede ...
- 20165320 预备作业2:技能学习心得与C语言学习
一.技能学习心得 1.你有什么技能比大多数人好? 我觉得我的篮球打得比一般的人好吧,但是也仅仅掌握了大部分基本的篮球技巧,算不上精通. 2.针对这个技能的获取你有什么成功的经验? 我觉得要打好篮球需要 ...
- ubuntu更新源列表
1. 备份源列表 sudo cp /etc/apt/sources.list /etc/apt/sources.list_backup 2.修改更新源 打开源列表 sudo gedit /etc/ap ...
- vs2010,vs2012注释快捷键
注释:VS2010是(Ctrl+E,C),VS2012是(Ctrl+K, Ctrl+C) 反注释:VS2010是(Ctrl+E,U),VS2012是(Ctrl+K, Ctrl+U)
- quartz的一个误导
quartz文档提到,如果在集群环境下,最好将配置项org.quartz.jobStore.txIsolationLevelSerializable设置为true 问题: 这个选项在mysql下会非常 ...
- 四、Springboot Debug调试
描述: 在使用maven插件执行spring-boot:run进行启动的时候,如果设置的断点进不去,要进行以下的设置. 1.添加jvm参数配置 在spring-boot的maven插件加上jvmArg ...
- Token机制,防止web页面重复提交
1.业务要求:页面的数据只能被点击提交一次 2.发生原因: 由于重复点击或者网络重发,或者nginx重发等情况会导致数据被重复提交 3.解决办法: 集群环境:采用token加redis(redis单线 ...