Python threading模块
2种调用方式
直接调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import threading import time def sayhi(num): #定义每个线程要运行的函数 print ( "running on number:%s" % num) time.sleep( 3 ) if __name__ = = '__main__' : t1 = threading.Thread(target = sayhi,args = ( 1 ,)) #生成一个线程实例 t2 = threading.Thread(target = sayhi,args = ( 2 ,)) #生成另一个线程实例 t1.start() #启动线程 t2.start() #启动另一个线程 print (t1.getName()) #获取线程名 print (t2.getName()) |
继承式调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import threading import time class MyThread(threading.Thread): def __init__( self ,num): threading.Thread.__init__( self ) self .num = num def run( self ): #定义每个线程要运行的函数 print ( "running on number:%s" % self .num) time.sleep( 3 ) if __name__ = = '__main__' : t1 = MyThread( 1 ) t2 = MyThread( 2 ) t1.start() t2.start() |
第二种有点傻
基本语法
is_alive() 当前活跃的线程
例子:
car1 = threading.Thread(target=car,args=('bmw',))car1.start()print(car1.is_alive())if car1.is_alive(): print('33')if not car1.is_alive(): print('444')
执行结果:
bmw wait red lightTrue33
例子对比:
car1 = threading.Thread(target=car,args=('bmw',))# car1.start() 注释掉print(car1.is_alive()) if car1.is_alive(): print('33')if not car1.is_alive(): print('444')
执行结果:
False444
Join ()
等待!其实就wait()。
等待该线程执行完毕
Daemon()
守护进程!有句话怎么说来着!守护进程被吞噬!
# _*_coding:utf-8_*_import timeimport threadingstart_time=time.time()def run(n): print('[%s]------running----\n' % n) time.sleep(2) print('--done--%s'%n)def run2(n): print('[%s]------running----\n' % n) time.sleep(5) print('--done--%s'%n)lis_1=[]t1 = threading.Thread(target=run, args=('run%1',))t2 = threading.Thread(target=run2, args=('run%2',))lis_1.append(t1)lis_1.append(t2)# t2.setDaemon(True)# 将main线程设置为Daemon线程,它做为程序主线程的守护线程,当主线程退出时,m线程也会退出,由m启动的其它子线程会同时退出,不管是否执行完任务t1.start()t2.start()# 看下就懂了,不懂试一试就想起来了t1.join()t2.join()print("---end time----",time.time()-start_time)
线程锁(互斥锁Mutex)
lock()
为什么上锁?因为好多线程同时修改一个数据,有先后顺序,有的没干完,就被gil了,所以对修改数据的地方加把锁,保证该数据的正确性!
lock
=
threading.Lock()
#生成全局锁
不带锁例子:
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 addNum(): global num #在每个线程中都获取这个全局变量 print ( '--get num:' ,num ) time.sleep( 1 ) num - = 1 #对此公共变量进行-1操作 num = 100 #设定一个共享变量 thread_list = [] for i in range ( 100 ): t = threading.Thread(target = addNum) t.start() thread_list.append(t) for t in thread_list: #等待所有线程执行完毕 t.join() print ( 'final num:' , num ) |
带锁例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import time import threading def addNum(): global num #在每个线程中都获取这个全局变量 print ( '--get num:' ,num ) time.sleep( 1 ) lock.acquire() #修改数据前加锁 num - = 1 #对此公共变量进行-1操作 lock.release() #修改后释放 num = 100 #设定一个共享变量 thread_list = [] lock = threading.Lock() #生成全局锁 for i in range ( 100 ): t = threading.Thread(target = addNum) t.start() thread_list.append(t) for t in thread_list: #等待所有线程执行完毕 t.join() print ( 'final num:' , num ) |
RLock(递归锁)
这个主要针对函数甲里边包涵函数乙,函数乙又有函数丙
绕进去了,很麻烦,用lock的话容易死循环,所以用Rlock,一键上锁,保证不乱。例子看看就好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | import threading,time def run1(): print ( "grab the first part data" ) lock.acquire() global num num + = 1 lock.release() return num def run2(): print ( "grab the second part data" ) lock.acquire() global num2 num2 + = 1 lock.release() return num2 def run3(): lock.acquire() res = run1() print ( '--------between run1 and run2-----' ) res2 = run2() lock.release() print (res,res2) if __name__ = = '__main__' : num,num2 = 0 , 0 lock = threading.RLock() for i in range ( 10 ): t = threading.Thread(target = run3) t.start() while threading.active_count() ! = 1 : print (threading.active_count()) else : print ( '----all threads done---' ) print (num,num2) |
Semaphore(信号量)
互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import threading,time def run(n): semaphore.acquire() time.sleep( 1 ) print ( "run the thread: %s\n" % n) semaphore.release() if __name__ = = '__main__' : num = 0 semaphore = threading.BoundedSemaphore( 5 ) #最多允许5个线程同时运行 for i in range ( 20 ): t = threading.Thread(target = run,args = (i,)) t.start() while threading.active_count() ! = 1 : pass #print threading.active_count() else : print ( '----all threads done---' ) print (num) |
Events
重点,标识符,event可以理解成对全局变量不停的修改,!!!!!!这个我感觉后边能用的到,用event来验证result
语法有
event = threading.Event()
创建标识符
event.set( )
设置标识符
event.wait( )
等待标识符出现,一旦出现立刻执行后边的代码
print(‘杀啊!!’)event.wait()print( ‘撤退!!,杀个瘠薄’
event.clear( )
清空标志位
通过Event来实现两个或多个线程间的交互
红绿灯例子!!
import timeimport threadingevent=threading.Event()def car(name): while True: if event.is_set(): print('%s is runing'%name) time.sleep(1) else: print('%s wait red light' % name) event.wait() time.sleep(1)def light(): conent = 0 event.set() while True: if conent >5 and conent <10: event.clear() print('\033[41;1mred light is on ....\033[0m') elif conent >10: event.set() conent = 0 else: print('\033[42;1mgreen is come!\033[0m') time.sleep(1) conent += 1light = threading.Thread(target=light,)car2 = threading.Thread(target=car,args=('tesla',))car1 = threading.Thread(target=car,args=('bmw',))light.start()car1.start()car2.start()
运行结果