Python-多线程
一、python多线程的特点
1、一个进程至少有一个线程
2、多任务可以由多进程,或一个进程内的多线程完成
3、一个python进程只能占用一个cpu内核:每个线程执行前都必须获得GIL锁(Global Interpreter Lock),执行100行字节码后,再释放锁;这样,多个子线程可以在一个cpu内核中交替运行
4、每个python进程相互独立,都拥有一个GIL锁;可通过多个python进程实现多核
二、启动多线程
def func(num): print(num) print('当前主线程名称:',threading.current_thread().name) #返回主线程名称 for i in range(10): #多线程 t = threading.Thread(target=func,args=(i,)) #创建线程实例 print(t.getName()) #返回每个子线程名称 t.start() #启动线程
三、获取锁(多线程共享同一个数据时,通过锁确保数据的一致性)
a = 0 lock = threading.Lock() #创建锁 def func1(num): global a lock.acquire() #获取锁 a += num a -= num lock.release() #释放锁 for i in range(1000): t = threading.Thread(target=func1,args=(i,)) t.start() print(a) #a=0
四、join():等待当前运行的线程结束再执行下一个线程
import time start = time.time() def func2(num): #func2:间隔2s打印一次 time.sleep(2) print(num) threads = [] for i in range(10): #将10个子线程都保存在threads中,并同时启动10个子线程 t = threading.Thread(target=func2,args=(i,)) threads.append(t) t.start() for t in threads: #等待所有的子线程结束再运行主线程 t.join() end = time.time() run_time = end - start #十个子线程的运行时间为2s左右 print(run_time)
五、setDaemon(True):当主线程结束时,强制结束当前运行的所有子线程
import time start = time.time() def func2(num): #func2:间隔2s打印一次 time.sleep(2) print(num)for i in range(10): #将10个子线程都保存在threads中,并同时启动10个子线程 t = threading.Thread(target=func2,args=(i,)) t.setDaemon(True) #当主线程结束时,强制结束子线程t t.start() time.sleep(N) print('结束主线程')
设置time.sleep(N)中的N,会导致结果不一样:
1、设置N<2时,结果只会打印最后一句:‘结束主线程’;因为主线程运行时间小于2s,且主线程结束时强制停止func2;因此,不会打印num
2、设置N>2时,结果会打印所有的num和最后一句‘结束主线程’;因为在主程序结束前,所有的子线程已经运行完毕
六、Timer定时器:指定n秒后执行指定线程
from threading import Timer import time def func3(num): print(num) threads = [] start = time.time() for i in range(10): t = Timer(2,function=func3,args=(i,)) #创建定时器:等待2秒之后再执行func3;10个子线程并发执行 threads.append(t) t.start() for t in threads: t.join() end = time.time() run_time = end - start print(run_time) #运行时间2s左右