Python学习之路 – join与setDaemon

发布于 2021-03-13  95 次阅读


Join & Daemon

join()方法:主线程A中,创建了子线程B,并且在主线程A中调用了B.join()方法(或多个线程中的一个join()方法),那么,主线程A会在调用的地方等待,直到子线程B完成操作后,才可以接着往下执行。总结一句话就是主线程开始,等待当前子线程完成,才结束主线程。

import threading, time

class MyThread(threading.Thread):
    def __init__(self, id):
        super(MyThread, self).__init__()
        self.id = id
        print("I am slave thread %s " % self.name)
    def run(self):
        time.sleep(6) # 模拟阻塞
        print("%s running:%s" % (self.name, self.id))

threads = []
for i in range(5):
    threads.append(MyThread(i)) # 生成线程实例

for t in threads:
    t.start()  # 由主线程启动所有线程

for i in range(5):
    print("I am in Master Thread.", i) # 返回到主线程继续
Python学习之路 – join与setDaemon插图

以上执行结果没有使用join()方法;主线程先生成子线程,子线程执行,由于执行过程中堵塞,返回执行主线程内容,此间暂停了等主线程执行完后,子线程执行结束返回了指向结果

加入join()方法执行

import threading, time

class MyThread(threading.Thread):
    def __init__(self, id):
        super(MyThread, self).__init__()
        self.id = id
        print("I am slave thread %s " % self.name)
    def run(self):
        time.sleep(6) # 模拟阻塞
        print("%s running:%s" % (self.name, self.id))

threads = []
for i in range(5):
    threads.append(MyThread(i)) # 生成线程实例

for t in threads:
    t.start()  # 由主线程启动所有线程
t.join()  #等待所有线程运行结束,没有这条,由于线程里run中有阻塞,
# 故主线程不等,而直接运行下面的for i

for i in range(5):
    print("I am in Master Thread.", i) # 返回到主线程继续

总结:join()方法就是为了让主线程等待子线程执行完并返回结果后,再执行主线程剩下的内容。子线程不执行完,主线程就一直等待状态,没有加join()方法时主线程只是开启子线程,至于子线程执行多久何时返回值,主线程暂时不管,仍然执行剩下的主程序

SetDaemon()方法

主线程A中,创建了子线程B,并且在主线程A中调用了B.setDaemon()方法,把主线程A设置为守护线程,这时候,要是主线程A执行结束了,就不管子线程B是否完成,一并和主线程A退出。这就是setDaemon()方法的含义。

跟随主线程,主线程结束,子线程直接结束,步调和主线程保持一致

import threading, time

class Mythread(threading.Thread):
    def __init__(self, id):
        super(Mythread, self).__init__()
        self.id = id
        print("I am slave thread %s" % self.name)
    def run(self):
        x = 0
        if self.id == 0:
            time.sleep(5)
            print("%s running:%s" % (self.name,self.id))
        else:
            time.sleep(2)
            print("%s running:%s" % (self.name, self.id))

threads = []
for i in range(5):
    threads.append(Mythread(i))

threads[0].setDaemon(True) # 0号线程  不受保护,主线程结束时,如果没有运行完也结束掉


for t in threads:
    t.start()
t.join()

for i in range(5):
    print("I am in Master Thread.", i)
Python学习之路 – join与setDaemon插图2

Threads[0].setDaemon(True)对0号线程设置不受保护,主线程结束时,如果没有运行完也结束掉,在程序中对Threads-0阻塞了5秒,而其他的子线程2秒,0号线程设置了不受保护,所以在主线程执行完后,就退出了,不再等待。而其他子线程不收影响,可以把Thread[0]换成其它子线程,效果是一样的。


生之逢时,为之奋斗。