问题背景
在 Python 中,想要充分利用多线程的优势,就需要对 threading 模块中的 Thread 类有一定的了解。这里有一个非常简单的多线程程序,用于帮助我们理解 threading.Thread.join 方法。
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(),那么输出结果又会是怎样的?
解决方法
- 不注释掉 join() 方法
如果我们不注释掉 thread1.join() 和 thread2.join(),那么输出结果如下:
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
- 注释掉 join() 方法
如果我们注释掉 thread1.join() 和 thread2.join(),那么输出结果如下:
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() 方法的作用,我们修改一下上面的代码:
import threading
val = 0
def increment(msg,sleep_time):
global val
print("Inside increment")
for x in range(10):
val += 1
print("%s : %d\n" % (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()
如果我们运行这段代码,那么输出结果如下:
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() 这两个方法,让主线程等待这两个线程终止后才继续执行。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。