python中threading的join和setDaemon的区别和用法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_33718563/article/details/87872805

python中多线程编程时,经常会用到join()和setDaemon()方法,下面分别简单介绍下两种方式的概念及用法。

1.join()方法 

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

     用法:

join[timeout]

     里面的参数是可选的,代表线程运行的最大时间,即如果超过了这个时间,不管这个子线程有没有执行完毕都会被回收,然后主线程或函数都会被接着执行的。

    (1)示例01:

import threading
import time


class MyThread(threading.Thread):
    def __init__(self, id):
        threading.Thread.__init__(self)
        self.id = id

    def run(self):
        time.sleep(10)
        print self.id


if __name__ == "__main__":
    t1 = MyThread(999)
    t1.start()
    for i in range(5):
        print i

运行结果:

0
1
2
3
4
999

分析:在机器上运行时,打印“4”和“9”之间会有明显的停顿,线程t1 start后,主线程并没有等待t1运行结束后再执行,而是先把5次循环打印执行完毕后,然后sleep(10)后,线程t1把传进去的999才打印出来

    (2)示例02:在示例01的基础上添加join()方法

import threading
import time


class MyThread(threading.Thread):
    def __init__(self, id):
        threading.Thread.__init__(self)
        self.id = id

    def run(self):
        time.sleep(10)
        print self.id


if __name__ == "__main__":
    t1 = MyThread(999)
    t1.start()
    t1.join()
    for i in range(5):
        print i

运行结果:

999
0
1
2
3
4

分析:在打印“999”之前会有明显的停顿,原因是线程t1 start后,主线程停在了join()方法处,等sleep(10)后,线程t1操作结束被join,接着,主线程继续循环打印。

    (3)示例03:在示例02的基础上添加setDaemon()方法

      在主线程中A中,创建了子线程B,并且在主线程A中调用了B.setDaemon()方法,注意必须在start()方法之前设置,这个意思:

使用setDaemon()和守护线程这方面知识有关, 比如在启动线程前设置thread.setDaemon(True),就是设置该线程为守护线程,表示该线程是不重要的,进程退出时不需要等待这个线程执行完成。
这样做的意义在于:避免子线程无限死循环,导致退不出程序,也就是避免楼上说的孤儿进程。

示例: 设置子线程随主线程的结束而结束

import threading
import time


class MyThread(threading.Thread):
    def __init__(self, id):
        threading.Thread.__init__(self)
        self.id = id

    def run(self):
        time.sleep(5)
        print "This is " + self.getName()


if __name__ == "__main__":
    t1 = MyThread(999)
    t1.setDaemon(True)
    t1.start()
    print "I am the father thread."

运行结果:

I am the father thread.

       可以看出,子线程t1的内容并没有打印,原因是t1.setDaemon(True)的操作,将该子线程设置为守护线程,根据setDaemon()的含义,主线程打印完内容后就结束了,不再管子线程是否执行完毕。         程序运行中,执行一个主进程,如果主线程又创建了一个子线程,主线程和子线程就兵分两路,分别运行,那么当主线程完成想要退出时,会检验子线程是否完整。如果子线程未完成,则会等待子线程完成后再退出。但有时候我们需要的是,只要主线程完成了,不管子线程是否完成,都要和主线程一起退出,这时就可以用setDaemon方法了。

       所以,join()和Daemon()的区别如上述的例子,他们的思路基本上是相反的。

猜你喜欢

转载自blog.csdn.net/sinat_33718563/article/details/87872805