Python中的多線程
阿新 • • 發佈:2018-07-13
info print pre lock map __main__ color 開啟 self
1、什麽是線程
進程其實不是一個執行單位,進程是一個資源單位
每個進程內自帶一個線程,線程才是CPU上的執行單位
如果把操作系統比喻為一座工廠
在工廠內每造出一個車間===》啟動一個進程
每個車間內至少有一條流水線===》每個進程內至少有一個線程
線程==》單指代碼的執行過程
進程==》資源的申請與銷毀的過程
2、進程VS線程
1)內存共享or隔離
多個進程內存空間彼此隔離
同一進程下的多個線程共享該進程內的數據
2)創建速度
造線程的速度要遠遠快於造進程
一、開啟線程的兩種方式(重點)
方式一:導入Thread模塊
1 fromthreading import Thread 2 import time 3 5 def task(name): 6 print(‘%s is running‘ %name) 7 time.sleep(3) 8 print(‘%s is done‘ %name) 9 if __name__ == ‘__main__‘: 10 t=Thread(target=task,args=(‘子線程‘,)) 11 t.start() 12 print(‘主‘)
方式二:創建類繼承Thread
1 from threading importThread 2 import time 3 4 6 # class Mythread(Thread): 7 # def run(self): 8 # print(‘%s is running‘ %self.name) 9 # time.sleep(3) 10 # print(‘%s is done‘ %self.name) 11 # 12 # if __name__ == ‘__main__‘: 13 # t=Mythread() 14 # t.start() 15 # print(‘主‘)
二、線程VS進程(重點)
1 # from threading import Thread 2 # from multiprocessing import Process 3 # import time 4 # 5 # def task(name): 6 # print(‘%s is running‘ %name) 7 # time.sleep(3) 8 # print(‘%s is done‘ %name) 9 # 10 # if __name__ == ‘__main__‘: 11 # t=Thread(target=task,args=(‘子線程‘,)) 12 # # t=Process(target=task,args=(‘子進程‘,)) 13 # t.start() 14 # print(‘主‘)
線程運行結果:
進程運行結果:
2)同一進程下的多個線程共享該進程內的數據(了解知識點)
1 # from threading import Thread 2 # import time 3 # 4 # x=100 5 # def task(): 6 # global x 7 # x=0 8 # 9 # if __name__ == ‘__main__‘: 10 # t=Thread(target=task,) 11 # t.start() 12 # # time.sleep(3) 13 # t.join() 14 # print(‘主‘,x)View Code
3)查看pid(了解知識點)
註意:一個進程中的子線程pid相同
1 from threading import Thread 2 import time,os 3 4 def task(): 5 print(os.getpid()) 6 7 if __name__ == ‘__main__‘: 8 t=Thread(target=task,) 9 t.start() 10 print(‘主‘,os.getpid())View Code
三、線程對象的其他方法和屬性(熟悉知識點)
1)主進程等子進程是因為主進程要給子進程收屍
2)進程必須等待其內部所有線程都運行完畢才結束
1 # from threading import Thread 2 # import time 3 # 4 # def task(name): 5 # print(‘%s is running‘ %name) 6 # time.sleep(3) 7 # print(‘%s is done‘ %name) 8 # if __name__ == ‘__main__‘: 9 # t=Thread(target=task,args=(‘子線程‘,)) 10 # t.start() 11 # print(‘主‘) 12 #View Code
1 from threading import Thread,current_thread,active_count,enumerate 2 import time 3 4 5 def task(): 6 print(‘%s is running‘ % current_thread().name) 7 time.sleep(3) 8 print(‘%s is done‘ % current_thread().name) 9 10 11 if __name__ == ‘__main__‘: 12 t = Thread(target=task,name=‘xxx‘) 13 t.start() 14 # t.join() 15 # print(t.is_alive()) 16 # print(t.getName()) 17 # print(t.name) 18 # print(‘主‘,active_count()) 19 # print(enumerate()) 20 21 # t.join() 22 current_thread().setName(‘主線程‘) 23 print(‘主‘,current_thread().name)View Code
四、守護線程(熟悉知識點)
守護線程(daemon)會在本進程內所有非守護的線程都死掉了才跟著死
即:
守護線程其實守護的是整個進程的運行周期(進程內所有的非守護線程都運行完畢)
1 # from threading import Thread,current_thread 2 # import time 3 # 4 # 5 # def task(): 6 # print(‘%s is running‘ % current_thread().name) 7 # time.sleep(3) 8 # print(‘%s is done‘ % current_thread().name) 9 # 10 # 11 # if __name__ == ‘__main__‘: 12 # t = Thread(target=task,name=‘守護線程‘) 13 # t.daemon=True 14 # t.start() 15 # print(‘主‘)守護進程
1 from threading import Thread 2 import time 3 def foo(): 4 print(123) 5 time.sleep(3) 6 print("end123") 7 8 def bar(): 9 print(456) 10 time.sleep(1) 11 print("end456") 12 13 14 t1=Thread(target=foo) 15 t2=Thread(target=bar) 16 17 t1.daemon=True 18 t1.start() 19 t2.start() 20 print("main-------") 21 22 ‘‘‘ 23 123 24 456 25 main------- 26 end456 27 28 ‘‘‘較迷惑人的守護進程
五、互斥鎖(熟悉知識點)
1 from threading import Thread,Lock 2 import time 3 4 mutex=Lock() 5 6 x=100 7 def task(): 8 global x 9 # mutex.acquire() 10 temp=x 11 time.sleep(0.1) 12 x=temp-1 13 # mutex.release() 14 15 if __name__ == ‘__main__‘: 16 t_l=[] 17 start=time.time() 18 for i in range(100): 19 t=Thread(target=task) 20 t_l.append(t) 21 t.start() 22 23 for t in t_l: 24 t.join() 25 26 stop=time.time() 27 print(x,stop-start)互斥鎖
六、死鎖現象與遞歸鎖(熟悉知識點)
如果用Lock(互斥鎖),會發生死鎖現象
遞歸鎖本質是一把鎖,可連續acqruie,但只有其上的計數為0時其他線程才可對其調用
1 from threading import Thread,Lock,active_count,RLock 2 import time 3 4 # mutexA=Lock() 5 # mutexB=Lock() 6 obj=RLock() #遞歸鎖的特點:可以連續的acquire 7 mutexA=obj 8 mutexB=obj 9 10 class Mythread(Thread): 11 def run(self): 12 self.f1() 13 self.f2() 14 15 def f1(self): 16 mutexA.acquire() 17 print(‘%s 拿到A鎖‘ %self.name) 18 19 mutexB.acquire() 20 print(‘%s 拿到B鎖‘ %self.name) 21 mutexB.release() 22 23 mutexA.release() 24 25 def f2(self): 26 mutexB.acquire() 27 print(‘%s 拿到B鎖‘ %self.name) 28 time.sleep(1) 29 30 mutexA.acquire() 31 print(‘%s 拿到A鎖‘ %self.name) 32 mutexA.release() 33 34 mutexB.release() 35 36 if __name__ == ‘__main__‘: 37 for i in range(10): 38 t=Mythread() 39 t.start() 40 # print(active_count())View Code
七、信號量(熟悉知識點)
信號量本質上還是鎖,但區別信號量是控制同一時刻並發執行的任務數
1 from threading import Thread,Semaphore,current_thread 2 import time,random 3 4 sm=Semaphore(5) 5 6 def task(): 7 with sm: 8 print(‘%s 正在上廁所‘ %current_thread().name) 9 time.sleep(random.randint(1,4)) 10 11 12 if __name__ == ‘__main__‘: 13 for i in range(20): 14 t=Thread(target=task) 15 t.start()信號量
Python中的多線程