当前位置:   article > 正文

关于python线程模块threading的学习总结:threading.Thread对象的join方法_threading.thread join

threading.thread join

如果想了解什么是线程,推荐看一看这篇文章,真的是生动形象:趣文:我是一个线程

1.子线程不使用join方法

join方法主要是会阻塞主线程,在子线程结束运行前,主线程会被阻塞等待。这里用一个例子来说明:

  1. # encoding=utf8
  2. import threading
  3. import time
  4. def now():
  5. return '%.3f' % time.time()
  6. def test(n):
  7. print 'start %s at: %s' % (n, now())
  8. time.sleep(n)
  9. print 'end %s at: %s' % (n, now())
  10. def main():
  11. print 'start main at: %s' % now()
  12. threadpool = []
  13. for i in xrange(1, 4):
  14. th = threading.Thread(target=test, args=(i,))
  15. threadpool.append(th)
  16. for th in threadpool:
  17. th.start()
  18. # for th in threadpool:
  19. # th.join()
  20. print 'main end at: %s' % now()
  21. if __name__ == '__main__':
  22. main()

在上面的例子中,每个子线程都会执行test方法,为了方便看结果,使每个子线程的sleep时间不同。

当前只是调用了每个子线程的start方法,并没有调用join方法,此时运行结果:

  1. start main at: 1521721709.912
  2. start 1 at: 1521721709.913
  3. start 2 at: 1521721709.913
  4. start 3 at: 1521721709.913
  5. main end at: 1521721709.913
  6. end 1 at: 1521721710.913
  7. end 2 at: 1521721711.913
  8. end 3 at: 1521721712.913

通过结果可以看出,主线程完成第一次打印后(start main at: 1521721709.912),其他子线程同时开始,但是主线程并没有等待子线程结束才结束,主线程继续执行第二次打印(main end at: 1521721709.913),接着其他子线程因为各自sleep的时间不同而相继结束。

2.子线程使用join方法

下面再看一下使用join方法后的结果(将上面注释掉的部分取消):

  1. start main at: 1521722097.382
  2. start 1 at: 1521722097.382
  3. start 2 at: 1521722097.382
  4. start 3 at: 1521722097.382
  5. end 1 at: 1521722098.382
  6. end 2 at: 1521722099.382
  7. end 3 at: 1521722100.383
  8. main end at: 1521722100.383

不难看出,主线程阻塞等待子线程完成后,自己才结束运行。

3.join方法的timeout参数

然后可以给在join函数传一个timeout参数的,看看它的作用是什么,这里修改了一下代码:

  1. # encoding=utf8
  2. import threading
  3. import time
  4. def now():
  5. return '%.3f' % time.time()
  6. def test(n):
  7. while 1:
  8. print str(n) * 6
  9. time.sleep(5)
  10. def main():
  11. print 'start main at: %s' % now()
  12. threadpool = []
  13. for i in xrange(1, 3):
  14. th = threading.Thread(target=test, args=(i, ))
  15. threadpool.append(th)
  16. for th in threadpool:
  17. th.start()
  18. for th in threadpool:
  19. th.join(5)
  20. print 'main end at: %s' % now()
  21. if __name__ == '__main__':
  22. main()

这里设置每个线程的timeout都是5,运行部分结果如下:

  1. start main at: 1521723210.825
  2. 111111
  3. 222222
  4. 222222
  5. 111111
  6. main end at: 1521723220.825
  7. 111111
  8. 222222
  9. 111111
  10. 222222
  11. ......

因为每个子线程执行的是一个while循环,实际上是会一直运行下去的(两个子线程一直打印111111,222222),如果不给join方法设置timeout,那么主线程会一直等下去,永远不会执行最后的“print 'main end at: %s' % now()”语句,但是上面的代码设置了timeout为5秒,通过执行结果可以看出,主线程一共等待了10秒后结束了自己的运行。所以可以知道,join方法的timeout参数表示了主线程被每个子线程阻塞等待的时间。

4.说说setDaemon

使用join方法是为了让主线程等待子线结束后再做其他事情,setDaemon方法正好相反,它是为了保证主线程结束的时候,整个进程就结束,不会等待所有子线程执行完才结束。修改一下上面的代码:

  1. # encoding=utf8
  2. import threading
  3. import time
  4. def now():
  5. return '%.3f' % time.time()
  6. def test(n):
  7. time.sleep(n)
  8. print '%s has ran' % (str(n) * 6)
  9. def main():
  10. print 'start main at: %s' % now()
  11. threadpool = []
  12. for i in xrange(2):
  13. th = threading.Thread(target=test, args=(i, ))
  14. threadpool.append(th)
  15. for th in threadpool:
  16. th.setDaemon(True)
  17. th.start()
  18. print 'main end at: %s' % now()
  19. if __name__ == '__main__':
  20. main()

以下是运行结果:

  1. start main at: 1521726104.773
  2. 000000 has ran
  3. main end at: 1521726104.773

通过结果可以看出,虽然创建了两个子线程,第一个子线程的sleep时间为0,所以可以和主线程同时执行,但是第二个子线程本身会先sleep1秒,这时候主线程已经执行完,整个程序退出,并没有接着执行第二个子线程。

需要注意的是,setDaemon方法要在调用start方法前设置。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/768887
推荐阅读
相关标签
  

闽ICP备14008679号