Python的进程和线程是使用的操作系统的原生线程和进程,其是去调用操作系统的相应接口实现
进程:之间不可直接共享数据,是资源的集合,进程必须有一个线程
线程:基于进程,之间可直接共享数据,可执行,只有所有的线程执行完毕程序才会退出
守护线程:生命值依赖于创建它的主线程,主程序亡,不管守护进程执行到何步也必须立即亡
多线程:不适用与CPU操作任务大的(如计算等),较适合于IO操作任务大的(如文件读写等)
线程实现
简单的线程:
1 import threading 2 #线程实现方法,取名任意 3 def run11(varx): 4 print("run11",varx) 5 #创建线程1 6 t1=threading.Thread(target=run11,args=("var1111",)) 7 t1.start() 8 #创建线程2 9 t2=threading.Thread(target=run11,args=("var2222",)) 10 t2.start()
类方法实现线程:
1 import threading 2 class DongThreadx(threading.Thread): 3 #构造方法,可以忽略不写 4 def __init__(self,varx): 5 #调用父类的构造方法 6 super(DongThreadx,self).__init__() 7 self.threadvar=varx 8 9 #run方法名不能更改 10 def run(self): 11 print("类线程:",self.threadvar) 12 #创建两个线程 13 t1=DongThreadx("dongxiaodong11") 14 t1.start() 15 t2=DongThreadx("dognxiaodong22") 16 t2.start()
守护线程实现:
t2=threading.Thread(target=run11,args=("var2222",)) t2.setDaemon(True) #使其成为主线程守护线程 t2.start()
线程补充
其他方法:
print(threading.current_thread()) #当前所属的线程 print(threading.active_count()) #当前活跃的总线程数 t1.join() #等待线程 t1 执行完毕
等待子线程执行完毕:
方法一:
使用join
1 import threading 2 import time 3 num=0 4 5 #延时并自增1 6 def run11(): 7 global num 8 time.sleep(2) 9 num+=1 10 11 #生成1000个线程 12 listthreadx=[] 13 for i in range(10000): 14 #创建线程 15 t1=threading.Thread(target=run11,args=()) 16 listthreadx.append(t1) 17 t1.start() 18 19 #等待1000个线程执行完毕,并输出结果 20 for t in listthreadx: 21 t.join() 22 23 print("总数为:",num)
方法二:
如果使用【threading.active_count()】的值为1,也说明子线程执行完毕
while threading.active_count() !=1: pass print("总数为:",num)
线程锁:
在多个线程中修改同一个数据时,可能会出现数据修改不正确,其是因为多核CPU和多线程造成的,在Python3中已经优化了此类错误,Python2可以使用线程锁进行优化:
1 lockx=threading.Lock() #得到锁实例 2 #延时并自增1 3 def run11(): 4 lockx.acquire() #获取线程锁 5 global num 6 num+=1 7 lockx.release() #释放线程锁
递归锁
【lockx=threading.RLock()】,实现锁和钥匙的一一对应,如果程序有内外嵌套锁时,可以使用其优化
信号量:
规定同时执行的最大线程数
1 blockx=threading.BoundedSemaphore(10) # 表示10为最大同时启动线程数 2 #延时并自增1 3 def run11(): 4 blockx.acquire() #获取线程锁 5 global num 6 num+=1 7 blockx.release() #释放线程锁
标志位:
在线程中封装了bool,实现了基本的标志位功能,其主要方法有:
eventx=threading.Event() #得到event实例
eventx.set() #设置标志位
eventx.wait()#等待标志位设置,一直处于阻塞
eventx.clear() #清除标志位
1 import threading 2 import time 3 4 eventx=threading.Event() #得到event实例 5 6 def run11(): 7 print("-----开始,等待标志位----") 8 eventx.wait()#等待标志位设置,一直处于阻塞 9 print("---阻塞取消,执行完成------") 10 eventx.clear() #清除标志位 11 12 def run22(times): 13 time.sleep(times) 14 eventx.set() #设置标志位 15 16 #执行线程 17 t1=threading.Thread(target=run11,args=()) 18 t1.start() 19 20 #延时线程 21 t2=threading.Thread(target=run22,args=(3,)) 22 t2.start()