threading.Thread.join()
方法用于阻塞当前线程,直到调用它的线程对象执行完成或者超时。这在需要等待子线程执行完毕后再继续执行主线程时非常有用。基于他这种特性,我讲用我的方法帮你选择你合适的解决方案。
问题背景
在 Python 中,想要充分利用多线程的优势,就需要对 threading 模块中的 Thread 类有一定的了解。这里有一个非常简单的多线程程序,用于帮助我们理解 threading.Thread.join 方法。
代码语言:javascript复制import threading
val = 0
def increment():
global val
print("Inside increment")
for x in range(100):
val = 1
print("val is now {} ".format(val))
thread1 = threading.Thread(target=increment, args=())
thread2 = threading.Thread(target=increment, args=())
thread1.start()
# thread1.join()
thread2.start()
# thread2.join()
这里有两个问题:
- 如果注释掉 thread1.join() 和 thread2.join(),那么输出结果会是怎样的?
- 如果不注释掉 thread1.join() 和 thread2.join(),那么输出结果又会是怎样的?
解决方法
1. 不注释掉 join() 方法
如果我们不注释掉 thread1.join() 和 thread2.join(),那么输出结果如下:
代码语言:javascript复制Inside increment
val is now 1
val is now 2
val is now 3
...
val is now 100
Inside increment
val is now 1
val is now 2
val is now 3
...
val is now 100
2. 注释掉 join() 方法
如果我们注释掉 thread1.join() 和 thread2.join(),那么输出结果如下:
代码语言:javascript复制Inside increment
Inside increment
val is now 1
val is now 1
val is now 2
val is now 3
...
val is now 99
val is now 2
val is now 3
...
val is now 98
val is now 99
val is now 100
比较输出结果
通过比较这两个输出结果,我们可以发现,如果注释掉 join() 方法,那么两个线程的输出结果是交织在一起的,这表明这两个线程是并发执行的。而如果不注释掉 join() 方法,那么两个线程的输出结果是按照顺序输出的,这表明这两个线程是串行执行的。
join() 方法的作用
join() 方法的作用是让调用它的线程等待另一个线程终止。在我们的例子中,thread1.join() 和 thread2.join() 的作用是让主线程等待 thread1 和 thread2 两个线程终止。如果不注释掉这两个方法,那么主线程就会等待这两个线程终止后才继续执行。而如果注释掉这两个方法,那么主线程就不会等待这两个线程终止,而是直接继续执行。
代码示例:
为了更清楚地了解 join() 方法的作用,我们修改一下上面的代码:
代码语言:javascript复制import threading
val = 0
def increment(msg,sleep_time):
global val
print("Inside increment")
for x in range(10):
val = 1
print("%s : %dn" % (msg,val))
time.sleep(sleep_time)
thread1 = threading.Thread(target=increment, args=("thread_01",0.5))
thread2 = threading.Thread(target=increment, args=("thread_02",1))
thread1.start()
thread1.join()
thread2.start()
thread2.join()
如果我们运行这段代码,那么输出结果如下:
代码语言:javascript复制Inside increment
thread_01 : 1
thread_01 : 2
thread_01 : 3
thread_01 : 4
thread_01 : 5
thread_01 : 6
thread_01 : 7
thread_01 : 8
thread_01 : 9
thread_01 : 10
Inside increment
thread_02 : 1
thread_02 : 2
thread_02 : 3
thread_02 : 4
thread_02 : 5
thread_02 : 6
thread_02 : 7
thread_02 : 8
thread_02 : 9
thread_02 : 10
从输出结果中,我们可以看到,这两个线程是按照顺序输出的,这表明这两个线程是串行执行的。这是因为我们在代码中使用了 thread1.join() 和 thread2.join() 这两个方法,让主线程等待这两个线程终止后才继续执行。
在这个例子中,主线程启动了一个子线程,并在子线程执行完成之前调用了 join()
方法来等待子线程执行完成。如有任何疑问可以评论区留言讨论。