运维之路-python threading多线程
转载:https://www.cnblogs.com/xiaobeibei26/p/6481707.html#3902738
Python之threading多线程
1、threading模块是Python里面常用的线程模块,多线程处理任务对于提升效率非常重要,先说一下线程和进程的各种区别,如图
概括起来就是
IO密集型(不用CPU)
多线程
计算密集型(用CPU)
多进程
使用线程和进程的目的都是为了提升效率
(1)单进程单线程,主进程、主线程
(2)自定义线程:
主进程
主线程
子线程
2、threading模块可以创建多个线程,不过由于GIL锁的存在,Python在多线程里面其实是快速切换,下面代码是创建线程的简单体验
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import time import threading def f0(): pass def f1(a1,a2): time.sleep( 5 ) f0() '''下面代码是直接运行下去的,不会等待函数里面设定的sleep''' t = threading.Thread(target = f1,args = ( 111 , 112 )) #创建线程 t.setDaemon( True ) #设置为后台线程,这里默认是False,设置为True之后则主线程不用等待子线程 t.start() #开启线程 t = threading.Thread(target = f1, args = ( 111 , 112 )) t.start() t = threading.Thread(target = f1, args = ( 111 , 112 )) t.start() #默认情况下程序会等线程全部执行完毕才停止的,不过可以设置更改为后台线程,使主线程不等待子线程,主线程结束则全部结束 |
在线程里面setDaemon()和join()方法都是常用的,他们的区别如下
(1)join ()方法:主线程A中,创建了子线程B,并且在主线程A中调用了B.join(),那么,主线程A会在调用的地方等待,直到子线程B完成操作后,
才可以接着往下执行,那么在调用这个线程时可以使用被调用线程的join方法。join([timeout]) 里面的参数时可选的,代表线程运行的最大时
间,即如果超过这个时间,不管这个此线程有没有执行完毕都会被回收,然后主线程或函数都会接着执行的,如果线程执行时间小于参数表示的
时间,则接着执行,不用一定要等待到参数表示的时间。
(2)setDaemon()方法。主线程A中,创建了子线程B,并且在主线程A中调用了B.setDaemon(),这个的意思是,把主线程A设置为守护线程,这
时候,要是主线程A执行结束了,就不管子线程B是否完成,一并和主线程A退出.这就是setDaemon方法的含义,这基本和join是相反的。此外,还有
个要特别注意的:必须在start() 方法调用之前设置,如果不设置为守护线程,程序会被无限挂起,只有等待了所有线程结束它才结束。
3、Python多线程里面的锁的
在多线程处理任务的时候,在同时操作一个数据的时候可能会造成脏数据,这时候就出现了锁的概念,也就是有一个线程在操作该数据的时候,就把
该数据锁上,防止别的线程操作,操作完了再释放锁。
4、Python多线程里面的event方法
该方法的具体用法是给线程设置红绿灯,红灯表示停,绿灯表示运行,如代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
import threading import time def do(event): print ( 'start' ) event.wait() #红灯,所有线程执行都这里都在等待 print ( 'end' ) event_obj = threading.Event() #创建一个事件 for i in range ( 10 ): #创建10个线程 t = threading.Thread(target = do,args = (event_obj,)) t.start() time.sleep( 5 ) event_obj.clear() #让灯变红,默认也是红的,阻塞所有线程运行 data = input ( '请输入要:' ) if data = = 'True' : event_obj. set () #变绿灯 |
结果如图