在 Python 的多线程编程中,经常碰到 thread.join()这样的代码。那么今天咱们用实际代码来解释一下 join 函数的作用。

第一,当一个进程启动之后,会默认产生一个主线程,因为线程是程序执行流的最小单元,当设置多线程时,主线程会创建多个子线程,在python中,默认情况下(其实就是setDaemon(False)),主线程执行完自己的任务以后,就退出了,此时子线程会继续执行自己的任务,直到自己的任务结束,例子见下面。

# coding: utf-8
# 测试多线程中join的功能
import threading, time
def doWaiting():
print 'start waiting1: ' + time.strftime('%H:%M:%S') + "\n"
time.sleep(3)
print 'stop waiting1: ' + time.strftime('%H:%M:%S') + "\n"
def doWaiting1():
print 'start waiting2: ' + time.strftime('%H:%M:%S') + "\n"
time.sleep(8)
print 'stop waiting2: ', time.strftime('%H:%M:%S') + "\n"
tsk = []
thread1 = threading.Thread(target = doWaiting)
thread1.start()
tsk.append(thread1)
thread2 = threading.Thread(target = doWaiting1)
thread2.start()
tsk.append(thread2)
print 'start join: ' + time.strftime('%H:%M:%S') + "\n" print 'end join: ' + time.strftime('%H:%M:%S') + "\n"

代码执行结果如下:

start waiting1: 22:24:20

start join: 22:24:20
start waiting2: 22:24:20 end join: 22:24:20 stop waiting1: 22:24:23 stop waiting2: 22:24:28

第二,当我们使用setDaemon(True)方法,设置子线程为守护线程时,主线程一旦执行结束,则全部线程全部被终止执行,可能出现的情况就是,子线程的任务还没有完全执行结束,就被迫停止,例子见下面。

 1 # coding: utf-8
2 # 测试多线程中join的功能
3 import threading, time
4 def doWaiting():
5 print 'start waiting1: ' + time.strftime('%H:%M:%S') + "\n"
6 time.sleep(3)
7 print 'stop waiting1: ' + time.strftime('%H:%M:%S') + "\n"
8 def doWaiting1():
9 print 'start waiting2: ' + time.strftime('%H:%M:%S') + "\n"
10 time.sleep(8)
11 print 'stop waiting2: ', time.strftime('%H:%M:%S') + "\n"
12 tsk = []
13 thread1 = threading.Thread(target = doWaiting)
14 thread1.setDaemon(True)
15 thread1.start()
16 tsk.append(thread1)
17 thread2 = threading.Thread(target = doWaiting1)
18 thread2.setDaemon(True)
19 thread2.start()
20 tsk.append(thread2)
21 print 'start join: ' + time.strftime('%H:%M:%S') + "\n"
22
23 print 'end join: ' + time.strftime('%H:%M:%S') + "\n"

代码执行结果如下:

start waiting1: 22:34:46

start waiting2: 22:34:46
start join: 22:34:46 end join: 22:34:46

第三,没有设置守护线程且没有设置join函数的timeout参数时,主线程将会一直等待,直到子线程全部结束,主线程才结束,程序退出。代码如下:

 1 # coding: utf-8
2 # 测试多线程中join的功能
3 import threading, time
4 def doWaiting():
5 print 'start waiting1: ' + time.strftime('%H:%M:%S') + "\n"
6 time.sleep(3)
7 print 'stop waiting1: ' + time.strftime('%H:%M:%S') + "\n"
8 def doWaiting1():
9 print 'start waiting2: ' + time.strftime('%H:%M:%S') + "\n"
10 time.sleep(8)
11 print 'stop waiting2: ', time.strftime('%H:%M:%S') + "\n"
12 tsk = []
13 thread1 = threading.Thread(target = doWaiting)
14 thread1.start()
15 tsk.append(thread1)
16 thread2 = threading.Thread(target = doWaiting1)
17 thread2.start()
18 tsk.append(thread2)
19 print 'start join: ' + time.strftime('%H:%M:%S') + "\n"
20 for tt in tsk:
21 tt.join()
22 print 'end join: ' + time.strftime('%H:%M:%S') + "\n"

代码执行结果如下:

start waiting1: 22:41:50

start join: 22:41:50
start waiting2: 22:41:50 stop waiting1: 22:41:53 stop waiting2: 22:41:58 end join: 22:41:58

第四,当没有设置守护线程且join函数的参数timeout=2时,主线程将会等待多个子线程timeout的累加和这样的一段时间,时间一到,主线程结束,但是并没有杀死子线程,子线程依然可以继续执行,直到子线程全部结束,程序退出。代码如下:

 1 # coding: utf-8
2 # 测试多线程中join的功能
3 import threading, time
4 def doWaiting():
5 print 'start waiting1: ' + time.strftime('%H:%M:%S') + "\n"
6 time.sleep(3)
7 print 'stop waiting1: ' + time.strftime('%H:%M:%S') + "\n"
8 def doWaiting1():
9 print 'start waiting2: ' + time.strftime('%H:%M:%S') + "\n"
10 time.sleep(8)
11 print 'stop waiting2: ', time.strftime('%H:%M:%S') + "\n"
12 tsk = []
13 thread1 = threading.Thread(target = doWaiting)
14 thread1.start()
15 tsk.append(thread1)
16 thread2 = threading.Thread(target = doWaiting1)
17 thread2.start()
18 tsk.append(thread2)
19 print 'start join: ' + time.strftime('%H:%M:%S') + "\n"
20 for tt in tsk:
21 tt.join(2)
22 print 'end join: ' + time.strftime('%H:%M:%S') + "\n"

代码执行结果如下:

start waiting1: 23:02:34

start waiting2: 23:02:34
start join: 23:02:34 stop waiting1: 23:02:37 end join: 23:02:38 stop waiting2: 23:02:42

第五,当设置守护线程join函数的参数timeout=2时,主线程将会等待多个子线程timeout的累加和这样的一段时间,时间一到,主线程结束,杀死未执行完的子线程,程序退出。代码如下:

 1 # coding: utf-8
2 # 测试多线程中join的功能
3 import threading, time
4 def doWaiting():
5 print 'start waiting1: ' + time.strftime('%H:%M:%S') + "\n"
6 time.sleep(3)
7 print 'stop waiting1: ' + time.strftime('%H:%M:%S') + "\n"
8 def doWaiting1():
9 print 'start waiting2: ' + time.strftime('%H:%M:%S') + "\n"
10 time.sleep(8)
11 print 'stop waiting2: ', time.strftime('%H:%M:%S') + "\n"
12 tsk = []
13 thread1 = threading.Thread(target = doWaiting)
14 thread1.setDaemon(True)
15 thread1.start()
16 tsk.append(thread1)
17 thread2 = threading.Thread(target = doWaiting1)
18 thread2.setDaemon(True)
19 thread2.start()
20 tsk.append(thread2)
21 print 'start join: ' + time.strftime('%H:%M:%S') + "\n"
22 for tt in tsk:
23 tt.join(2)
24 print 'end join: ' + time.strftime('%H:%M:%S') + "\n"

代码执行结果如下:

start waiting1: 23:23:57

start waiting2: 23:23:57
start join: 23:23:57 stop waiting1: 23:24:00 end join: 23:24:01

python多线程中join()的理解的更多相关文章

  1. python多线程中join()方法和setDaemon()方法的区别

    """ join()方法:主线程A中,创建了子线程B,并且在主线程中调用了B.join()方法,那么主线程A会在调用的地方等待,直到子线程B完成操作后,才可以接着往下执行 ...

  2. python 多线程中的同步锁 Lock Rlock Semaphore Event Conditio

    摘要:在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lo ...

  3. 彻底理解Python多线程中的setDaemon与join【配有GIF示意】

    在进行Python多线程编程时, join() 和 setDaemon() 是最常用的方法,下面说说两者的用法和区别. 1.join () 例子:主线程A中,创建了子线程B,并且在主线程A中调用了B. ...

  4. [转]Python多线程与多线程中join()的用法

    https://www.cnblogs.com/cnkai/p/7504980.html Python多线程与多进程中join()方法的效果是相同的. 下面仅以多线程为例: 首先需要明确几个概念: 知 ...

  5. 多线程中join的解释(转)

    文章来源:https://www.zhihu.com/question/61446671 这个join可以理解为“加入”,其含义与英语里面讲“Come on,join us”中的join类似.假设线程 ...

  6. 用C语言解决python多线程中的GIL问题

    在使用python多线程的时候为了解决GIL问题,有些代码得用C语言写,那么就得生成动态链接库. 当创建动态链接库时,独立位置信息(position independent)代码也需要生成.这可以帮助 ...

  7. Python多线程与多线程中join()的用法

    多线程实例 https://www.cnblogs.com/cnkai/p/7504980.html 知识点一:当一个进程启动之后,会默认产生一个主线程,因为线程是程序执行流的最小单元,当设置多线程时 ...

  8. 转载:Java多线程中join方法的理解

    转载自:http://uule.iteye.com/blog/1101994 thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A ...

  9. Java多线程中join方法的理解

    thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B. t.join( ...

随机推荐

  1. 神经网络(13)--具体实现:random initialization

    Θ应初始化为什么值 当我们是用logistic regression算法时,将θ初始化为0是可以的:但是如果在神经网络里面,将θ初始化为0是不可行的 若将Θ初始化为0的后果-the problem o ...

  2. Ubuntu 16.04LTS 安装和配置Bochs

    环境:VMWare14+Ubuntu16.04 安装Bochs2.6.9 1.去官网下载 下载 bochs-2.6.9.tar.gz 2.安装一系列的包 因为Bochs 需要在 X11 环境下运行,因 ...

  3. [TypeScript] Optional Chaining with TypeScript 3.7

    TypeScript 3.7 adds support for optional chaining. This lesson shows you how to use it in your code ...

  4. python -- 连接 orclae cx_Oracle的使用

    # 如果报错参考的资料 https://blog.csdn.net/white_xuqin/article/details/82878860 场景再现: python-cx_oracle报错" ...

  5. img src防缓存

    //加时间戳防缓存 var imgurl = "/pcms/headImg/${sessionScope.accountInfo.accountId}_cut.jpg?time=" ...

  6. windows下命令行切换目录

    1.切换目录 C:\Users\MACHENIKE> cd H:/www C:\Users\MACHENIKE>H: H:\www> 2.查看目录文件 H:\www>dir

  7. mysqli扩展有一系列的优势,相对于mysql扩展的提升主要优势有哪些?

    mysqli扩展有一系列的优势,相对于mysql扩展的提升主要优势有哪些? 面向对象接口 prepared语句支持(译注:关于prepare请参阅mysql相关文档) 多语句执行支持 事务支持 增强的 ...

  8. Problem 8 dp

    $des$ $sol$ 记 $f_i$ 表示考虑前 $i$ 个建筑, 并且第 $i$ 个建筑的高度不变的答案, 每次转移时枚举上一个不变的建筑编号, 中间的一段一定变成相同的高度, 并且高度小于等于两 ...

  9. Matlab中矩阵的数据结构

    在Matlab中,矩阵默认的数据类型是double, 并不是integer. 而且奇怪的是,矩阵乘法默认按照浮点数类型进行, 整数矩阵相乘会报错.另外,可以用a= int16(A)这种形式实现数据类型 ...

  10. 2D到3D视频转换 三维重建

    2D到3D视频转换(也称为2D到立体3D转换和立体转换)是将2D(“平面”)胶片转换为3D形式的过程,几乎在所有情况下都是立体声,因此它是创建图像的过程.每个眼睛来自一个2D图像. 内容 1概述 1. ...