zoukankan      html  css  js  c++  java
  • Python中threading的join和setDaemon的区别及用法

    Python多线程编程时经常会用到join()和setDaemon()方法,基本用法如下:

    join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
    setDaemon,将该线程标记为守护线程或用户线程
     

    1、join ()方法:主线程A中,创建了子线程B,并且在主线程A中调用了B.join(),那么,主线程A会在调用的地方等待,直到子线程B完成操作后,才可以接着往下执行,那么在调用这个线程时可以使用被调用线程的join方法。
    原型:join([timeout]),里面的参数时可选的,代表线程运行的最大时间,即如果超过这个时间,不管这个此线程有没有执行完毕都会被回收,然后主线程或函数都会接着执行的。

    import threading
    import time
    
    
    class MyThread(threading.Thread):
        def __init__(self, id):
            threading.Thread.__init__(self)
            self.id = id
    
        def run(self):
            x = 0
            time.sleep(10)
            print(self.id)
            print('线程结束:'+str(time.time()))
    
    if __name__ == "__main__":
        t1 = MyThread(999)
        print('线程开始:'+str(time.time()))
        t1.start()
        print('主线程打印开始:'+str(time.time()))
        for i in range(5):
            print(i)
        time.sleep(2)
        print('主线程打印结束:' + str(time.time()))

    线程开始:1497534590.2784667
    主线程打印开始:1497534590.2794669
    0
    1
    2
    3
    4
    主线程打印结束:1497534592.279581
    999
    线程结束:1497534600.2800388

    从打印结果可知,线程t1 start后,主线程并没有等线程t1运行结束后再执行,而是在线程执行的同时,执行了后面的语句。

    现在,把join()方法加到启动线程后面(其他代码不变)

    import threading
    import time
    
    
    class MyThread(threading.Thread):
        def __init__(self, id):
            threading.Thread.__init__(self)
            self.id = id
    
        def run(self):
            x = 0
            time.sleep(10)
            print(self.id)
            print('线程结束:'+str(time.time()))
    
    if __name__ == "__main__":
        t1 = MyThread(999)
        print('线程开始:'+str(time.time()))
        t1.start()
        t1.join()
        print('主线程打印开始:'+str(time.time()))
        for i in range(5):
            print(i)
        time.sleep(2)
        print('主线程打印结束:' + str(time.time()))

    线程开始:1497535176.5019968
    999
    线程结束:1497535186.5025687
    主线程打印开始:1497535186.5025687
    0
    1
    2
    3
    4
    主线程打印结束:1497535188.5026832

    线程t1 start后,主线程停在了join()方法处,等子线程t1结束后,主线程继续执行join后面的语句。 

    2、setDaemon()方法。主线程A中,创建了子线程B,并且在主线程A中调用了B.setDaemon(),这个的意思是,把主线程A设置为守护线程,这时候,要是主线程A执行结束了,就不管子线程B是否完成,一并和主线程A退出.这就是setDaemon方法的含义,这基本和join是相反的。此外,还有个要特别注意的:必须在start() 方法调用之前设置。

    import threading
    import time
    
    
    class MyThread(threading.Thread):
        def __init__(self, id):
            threading.Thread.__init__(self)
            self.id = id
    
        def run(self):
            x = 0
            time.sleep(10)
            print(self.id)
            print("This is:" + self.getName()) # 获取线程名称
            print('线程结束:' + str(time.time()))
    
    if __name__ == "__main__":
        t1 = MyThread(999)
        print('线程开始:'+str(time.time()))
        t1.setDaemon(True)
        t1.start()
        print('主线程打印开始:'+str(time.time()))
        for i in range(5):
            print(i)
        time.sleep(2)
        print('主线程打印结束:' + str(time.time())) 

    线程开始:1497536678.8509264
    主线程打印开始:1497536678.8509264
    0
    1
    2
    3
    4
    主线程打印结束:1497536680.8510408

    t1.setDaemon(True)的操作,将子线程设置为了守护线程。根据setDaemon()方法的含义,父线程打印内容后便结束了,不管子线程是否执行完毕了。

    如果在线程启动前没有加t1.setDaemon(True),输出结果为:

    线程开始:1497536865.3215919
    主线程打印开始:1497536865.3215919
    0
    1
    2
    3
    4
    主线程打印结束:1497536867.3217063
    999
    This is:Thread-1
    线程结束:1497536875.3221638

    程序运行中,执行一个主线程,如果主线程又创建一个子线程,主线程和子线程就分兵两路,分别运行,那么当主线程完成想退出时,会检验子线程是否完成,如果子线程未完成,则主线程会等待子线程完成后再退出;

    有时我们需要的是,子线程运行完,才继续运行主线程,这时就可以用join方法(在线程启动后面);

    但是有时候我们需要的是,只要主线程完成了,不管子线程是否完成,都要和主线程一起退出,这时就可以用setDaemon方法(在线程启动前面)。

    参考:

  • 相关阅读:
    ACM的算法分类 2015-04-16 14:25 22人阅读 评论(0) 收藏
    初学Larevel 2014-08-21 11:24 90人阅读 评论(0) 收藏
    初学PHP&MySQL 2014-05-31 12:40 92人阅读 评论(0) 收藏
    codeforces 570 E. Pig and Palindromes (dp)
    codeforces 570 D. Tree Requests (dfs序)
    poj 2157 Maze (bfs)
    cf 570 C. Replacement (暴力)
    cf 570B B. Simple Game(构造)
    cf 570 A. Elections
    hdu 1429胜利大逃亡(续) (bfs+状态压缩)
  • 原文地址:https://www.cnblogs.com/uncleyong/p/6987112.html
Copyright © 2011-2022 走看看