day9-守护线程

前文概述

我们说在不加join的时候,主线程和子线程完全是并行的,没有了依赖关系,你主线程执行了,我子线程也执行了。但是加了join之后,主线程依赖子线程执行完毕后才往下走。现在我们要把所有的子线程变成我的守护进程。

前文拓展

查看当前线程类型和当前运行线程的个数

import threading, time


def run(n):
    print("task:", n)
    time.sleep(2)
    print("task done", n, threading.current_thread())  # 查看每个线程的类型(主线程/子线程)


start_time = time.time()
for i in range(5):
    t = threading.Thread(target=run, args=("t-%s" %i,))
    t.start()

print("--------all thread has been finished", threading.current_thread(), threading.active_count())  # 查看线程类型和当前活动的线程个数
print("cost:", time.time() - start_time)

#运行输出

task: t-0
task: t-1
task: t-2
task: t-3
task: t-4
--------all thead has finished <_MainThread(MainThread, started 4320621376)> 6
cost: 0.0007410049438476562
task done t-1 <Thread(Thread-2, started 123145371865088)>
task done t-3 <Thread(Thread-4, started 123145382375424)>
task done t-0 <Thread(Thread-1, started 123145366609920)>
task done t-4 <Thread(Thread-5, started 123145387630592)>
task done t-2 <Thread(Thread-3, started 123145377120256)>

解析:可以看出函数外执行的print()是主线程执行的,函数里面的是子线程执行的,同时可以看见一个有6个线程,5个子线程,1个主线程。

下面来学习新的知识,首先来了解下什么是守护进程?

守护进程:假设你是主人,你有几个仆人,这些个仆人都是为你服务的。可以帮你做很多事情,一个主人可以有多个守护进程,它们为你服务的前提是,主线程必须存在,如果主线程不存在,则守护进程也没了。那守护进程有什么作用呢?可以为你管理一些资源,打开一些文件,监听一些端口,它可以做很多事情,这些完全可以自定义。

守护线程

功能:只要主线程执行完毕,它不管子线程有没有执行完毕,主线程就退出了。所以也就是把所有的子线程变成守护线程,那么主程序(主线程)就不会等待子线程执行完毕后退出整个程序(主线程),转而主线程会等待非守护线程执行完毕才退出整个程序(主线程),所以主程序(主线程)就不会管这些结束/或没结束的守护线程了,不重要。

用法:使用setDaemon(True)设置守护线程,

前提:必须在启动线程前设置

import threading, time


def run(n):
    print("task:", n)
    time.sleep(2)
    print("task done", n,threading.current_thread())


start_time = time.time()
for i in range(5):

    t = threading.Thread(target=run, args=("t-%s" %i,))
    # 把当前所有子线程设置为守护线程,一定要在start()之前设置
    t.setDaemon(True)
    t.start()

print("--------all thread has been finished",threading.current_thread(), threading.active_count())
print("cost:", time.time() - start_time)

#运行输出

task: t-0
task: t-1
task: t-2
task: t-3
task: t-4
--------all thread has been finished <_MainThread(MainThread, started 1100)> 6 #5个子线程,1个主线程
cost: 0.0035004615783691406

解析:在设置了将所有子线程设置为守护线程后,代表这些子线程的执行结束与否不再影响主线程的执行过程。所以主程序(主线程)只会等待主线程的所有程序执行完毕后才会退出程序,而不会等待所有子线程的执行完毕与否。所以在主程序执行完毕后退出了,同时所有子线程的执行被强制中断了,因而没有继续执行和输出task done...。这就是我们只能看到每个线程启动后的输出。

在之前不加入join()时,主线程执行和子线程是并行执行的,虽然主线程不等待子线程执行完毕后再往下执行,但是由于程序最后隐含了join()的方法,所以在主线程(程序)执行结束之前,依然会等待所有子线程的执行完毕才退出整个程序。

应用场景

写一个socketServer,每一个客户端连接过来,socketServer都会为这个连接分配一个新的线程,在启动新的线程之后,此时如果手动停止socketServer,在这种情况下,因为主线程的服务停止了,它不会等待子线程的执行结束而结束程序运行。这样,在socketServer上设置子线程为守护线程。当socketServer主程序(主线程)停止后,整个程序就全部退出了。

posted @ 2017-10-27 00:44  Mr.hu  阅读(146)  评论(0编辑  收藏  举报