python网络编程--线程join和Daemon(守护进程)
一:什么情况下使用join
join([timeout])调用join函数会使得主调线程阻塞,直到被调用线程运行结束或超时。
参数timeout是一个数值类型,用来表示超时时间,如果未提供该参数,那么主调线程将一直阻塞直到被调用线程结束
# -*- coding:utf-8 -*- __author__ = 'shisanjun' import threading import time def run(n): print("threading",n) time.sleep(2) start_time=time.time() thread_obj=[] #放线程对象 #起启50个线程,并发执行 for i in range(50): t=threading.Thread(target=run,args=("t%s" %i, )) t.start() thread_obj.append(t) #等待所有线程执行结束 for j in thread_obj: #主线程起动子线程,不会等子线程执行结束,所以要强制使用join等待每子线程执行结束 j.join() print("-----main thread cost time---",time.time()-start_time) #一共花了2秒 """ threading t0 threading t1 threading t2 threading t3 threading t4 threading t5 threading t6 threading t7 threading t8 threading t9 threading t10 threading t11 threading t12 threading t13 threading t14 threading t15 threading t16 threading t17 threading t18 threading t19 threading t20 threading t21 threading t22 threading t23 threading t24 threading t25 threading t26 threading t27 threading t28 threading t29 threading t30 threading t31 threading t32 threading t33 threading t34 threading t35 threading t36 threading t37 threading t38 threading t39 threading t40 threading t41 threading t42 threading t43 threading t44 threading t45 threading t46 threading t47 threading t48 threading t49 -----main thread cost time--- 2.3117313385009766 """
二:Daemon
setDaemon()可以参考Python文档说明。大概意思就是可以设置setDaemon的参数为True来表示将该线程指定为守护线程,如果参数为False就不指定线程为守护线程。设置setDaemon的参数为True之后。主线程和子线程会同时运行,主线程结束运行后,无论子线程运行与否,都会和主线程一起结束。
## -*- coding:utf-8 -*- __author__ = 'shisanjun' import threading import time def run(n): print("threading",n,threading.current_thread()) time.sleep(2) print("threading child") start_time=time.time() thread_obj=[] #放线程对象 #起启50个线程,并发执行 for i in range(50): t=threading.Thread(target=run,args=("t%s" %i, )) t.setDaemon(True)#就是把当前线程为守护线程,必须在start之前 t.start() thread_obj.append(t)#为了不阻塞后面的线程的启动,不在这里join,先放到一个列表里 # #等待所有线程执行结束 # for j in thread_obj: #主线程起动子线程,不会等子线程执行结束,所以要强制使用join等待每子线程执行结束 # j.join() #threading.current_thread()检查当前的线程名,可看是不是主线程,threading.active_count()检查活动线程个数 print("-----main thread cost time---",time.time()-start_time,threading.current_thread(),threading.active_count()) """ 主线程是主人,子线程仆人,如果没有主人,就没仆人。 不加join时候,主线程不会等子线程结束。加了join主线程依赖子线程结束,主线程默认有一个join 所有子线程变为守护线程,代表子线程变为仆人了,主线程还为等子线程结束嘛?主线程不会等子线程运行结束。主线程可以直接结束 所有子线程变为守护线程,主线程不会等子线程,他会等非守护线程结束。他是仆人不重要 加了t.setDaemon(True)程序不会主线程不会sleep2 例子:主线程和子线程,比做主人和仆人关系 谁是主人,谁是仆人,守护线程就是仆人,守护就是守护主人,主人die,仆人也die, 所以主线程结束了或者退出了,守护线程也会结束,而且不他不用告诉你。所以可以看到print("threading child")并没有输出。如果在主线程加了sleep,可能会看到一些 因为CPU执行速度太快了。 主线程 本来就是非守护线程 """
三:总结
1 Python 默认参数创建线程后,不管主线程是否执行完毕,都会等待子线程执行完毕才一起退出,有无join结果一样
2 如果创建线程,并且设置了daemon为true,即thread.setDaemon(True), 则主线程执行完毕后自动退出,不会等待子线程的执行结果。而且随着主线程退出,子线程也消亡。
3 join方法的作用是阻塞,等待子线程结束,join方法有一个参数是timeout,即如果主线程等待timeout,子线程还没有结束,则主线程强制结束子线程。
4 如果线程daemon属性为False, 则join里的timeout参数无效。主线程会一直等待子线程结束。
5 如果线程daemon属性为True, 则join里的timeout参数是有效的, 主线程会等待timeout时间后,结束子线程。此处有一个坑,即如果同时有N个子线程join(timeout),那么实际上主线程会等待的超时时间最长为 N * timeout, 因为每个子线程的超时开始时刻是上一个子线程超时结束的时刻。
- Python基础学习(5)网络编程socket、文件上传、粘包问题、socketserver、IO多路复用、线程与进程、进程池、线程池、上下文管理、协程
- java,python守护进程守护线程Daemon(经典好文)
- Python网络编程之线程与进程
- [Python网络编程]浅析守护进程后台任务的设计与实现
- Python学习第二十一天——线程进程续和网络编程
- python笔记9-多线程Threading之阻塞(join)和守护线程(setDaemon)
- Python网络编程之线程,进程
- [Python网络编程]浅析守护进程后台任务的设计与实现
- 并发编程实战 1.6. 守护线程 - Daemon线程
- python网络编程-进程间数据通信(Queue,Pipe ,managers)
- python 多线程中的守护线程与join的用法
- linux系统编程之进程(八):守护进程详解及创建,daemon()使用
- Linux下的c语言网络编程-将普通进程转换为守护进程
- 网络编程——第一篇 基础之进程线程
- 线程的停止,守护进程,Join方法问题
- 3.6 学网络编程 线程进程 多进程解决方法
- Python实现Daemon(守护)进程
- python 守护进程(daemon)
- 守护进程(daemon)编程规则
- Linux Daemon守护进程编程