python线程代码_python--(十步代码学会线程)
python--(十步代碼學會線程)
一.線程的創建
Thread實例對象的方法#isAlive(): 返回線程是否活動的.
#getname(): 返回線程名.
#setName(): 設置線程名.
threading模塊提供的一些方法:#threading.currentThread(): 返回當前的線程變量。
#threading.enumerate(): 返回一個包含正在運行的線程的list。正在運行指線程啟動后、結束前,不包括啟動前和終止后的線程。
#threading.activeCount(): 返回正在運行的線程數量,與len(threading.enumerate())有相同的結果
from threading importThreadfrom multiprocessing importProcess#第一種方法
deffunc(n):print(n)if __name__ == '__main__':
t= Thread(target=func, args=("我是線程",))
t.start()#p = Process(target=func, args=("我是進程",))
#p.start()
print("主進程結束.")#第二種方法
classMyThread(Thread):defrun(self):print("輝哥牛逼")if __name__ == "__main__":
t=MyThread()
t.start()print("主線程結束")
線程的兩種創建方式
importtimefrom threading importThreadfrom multiprocessing importProcessdeffunc(n):
num=0for n1 inrange(n):
num+=n1print("num",num)if __name__ == '__main__':
t_s_t=time.time()
t_list=[]for i in range(10):
t= Thread(target=func, args=(10,))
t.start()#速度特別快
t_list.append(t)
[tt.join()for tt int_list]
t_e_t=time.time()
t_dif_t= t_s_t - t_e_t #獲取了線程的執行時間
p_s_t=time.time()
p_list=[]for ii in range(10):
p= Process(target=func, args=(10,))
p.start()#速度非常快
p_list.append(p)
[pp.join()for pp inp_list]
p_e_t= time.time() #結束時間
p_dif_t = p_e_t - p_s_t #獲取進程執行時間
print('線程>>>>', t_dif_t)print('進程....', p_dif_t)print('主線程結束')
線程和進程的效率對比
線程的其他方法
#線程的一些其他方法#from threading import Thread#import threading#import time#from multiprocessing import Process#import os#
#def work():#import time#time.sleep(1)#print(threading.current_thread().getName()) #Thread-1#print(threading.current_thread()) #Thtrad-1#
#if __name__ == '__main__':##在主進程下開啟線程#t = Thread(target=work)#t.start()#
## print(threading.current_thread()) #主線程對象## print(threading.current_thread().getName()) #主線程名稱## print(threading.current_thread().ident) #主線程ID## print(threading.get_ident()) #主線程ID#
#time.sleep(3)#print(threading.enumerate()) #連同主線程在內有兩個運行的線程#print(threading.active_count()) #進程數#print("主線程/主進程")
View Code
二.數據共享
from threading importThreadfrom multiprocessing importProcess
num= 100
deffunc():globalnum
num=0if __name__ == '__main__':
t= Thread(target=func,)
t.start()
t.join()print(num)#p = Process(target=func,)
#p.start()
#p.join()
#print(num)
線程的數據是共享的
mport timefrom threading importThread,Lock#演示共享資源的時候,數據不安全的問題#num = 100#def func():#global num#num -= 1#mid = num#mid = mid - 1#time.sleep(0.00001)#num = mid#if __name__ == '__main__':#t_list = []#for i in range(10):#t = Thread(target=func,)#t.start()#t_list.append(t)#[tt.join() for tt in t_list]#print("主進程>>>>", num)
#通過鎖來解決數據不安全的問題,線程模塊里面引入的鎖
num = 100
deffunc(t_lock):globalnum
t_lock.acquire()
mid=num
mid= mid - 1time.sleep(0.0001)
num=mid
t_lock.release()if __name__ == '__main__':
t_lock= Lock() #鎖對象(同步鎖,互斥鎖)
t_list =[]for i in range(10):
t= Thread(target=func,args=(t_lock,))
t.start()
t_list.append(t)
[tt.join()for tt int_list]print("主進程>>>>",num)
線程共享資源不安全,加鎖解決
三.守護進程
守護進程 :
主進程代碼結束程序并沒有結束,并且主進程還存在,進程等待其他的子進程執行結束以后,為子進程收尸,注意一個問題:主進程的代碼運行結束守護進程跟著結束,
守護線程:
主線程等待所有非守護線程的結束才結束,主線程的代碼運行結束,還要等待非守護線程的執行完畢.這個過程中守護線程還存在
1 importtime2 from threading importThread3 from multiprocessing importProcess4 deffunc1(n):5 time.sleep(5)6 print(n)7 deffunc2(n):8 time.sleep(3)9 print(n)10 if __name__ == '__main__':11 #p1 = Process(target=func1,args=("我是子進程1號",))
12 ##設置守護進程,在start之前加
13 #p1.start()
14 #p2 = Process(target=func2,args=("我是子進程2號",))
15 #p2.daemon = True
16 #p2.start()
17 #print("子進程結束")
線程與進程守護進程對比
四.死鎖現象
鎖(同步鎖\互斥鎖): 保證數據安全,但是犧牲了效率,同步執行鎖內的代碼
死鎖現象 : 互相搶到了對方的需要的鎖,導致雙方相互等待,程序沒法進行
解決死鎖: 遞歸鎖,RLock?? #可以多次acquire,通過一個計數器來記錄被鎖了多少次,只有計數器為0的時候,大 家才能繼續搶鎖
importtimefrom threading importThread,LockclassMyThread(Thread):def __init__(self,lockA,lockB):
super().__init__()
self.lockA=lockA
self.lockB=lockBdefrun(self):
self.f1()
self.f2()deff1(self):
self.lockA.acquire()print('我拿了A鎖')
self.lockB.acquire()print('我是一個很好的客戶!')
self.lockB.release()
self.lockA.release()deff2(self):
self.lockB.acquire()
time.sleep(0.1)print('我拿到了B鎖')
self.lockA.acquire()print('我是一名合格的技師')
self.lockA.release()
self.lockB.release()if __name__ == '__main__':
lockA=Lock()
lockB=Lock()
t1=MyThread(lockA,lockB)
t1.start()
t2=MyThread(lockA,lockB)
t2.start()print('我是經理')
死鎖現象
importtimefrom threading import Thread,Lock,RLock #遞歸鎖
classMyThread(Thread):def __init__(self,lockA,lockB):
super().__init__()
self.lockA=lockA
self.lockB=lockBdefrun(self):
self.f1()
self.f2()deff1(self):
self.lockA.acquire()print('我拿了A鎖')
self.lockB.acquire()print('我是一個很好的客戶!')
self.lockB.release()
self.lockA.release()deff2(self):
self.lockB.acquire()
time.sleep(0.1)print('我拿到了B鎖')
self.lockA.acquire()print('我是一名合格的技師')
self.lockA.release()
self.lockB.release()if __name__ == '__main__':#lockA = Lock()
#lockB = Lock()
#lockA = lockB = Lock() #不要這么寫,別自己玩自己,鎖自己
lockA = lockB =RLock()
t1=MyThread(lockA,lockB)
t1.start()
t2=MyThread(lockA,lockB)
t2.start()print('我是經理')
解決死鎖線程方法
五.信號量
信號量: 控制同時能夠進入鎖內去執行代碼的線程數量(進程數量),維護了一個計數器,剛開始創建信號量的時候假如設置的是4個房間,進入一次acquire就減1 ,出來一個就+1,如果計數器為0,那么其他的任務等待,這樣其他的任務和正在執行的任務是一個同步的狀態,而進入acquire里面去執行的那4個任務是異步執行的.
importtimefrom threading importThread, Semaphoredeffunc1(s):
s.acquire()
time.sleep(1)print('大寶劍!!!')
s.release()if __name__ == '__main__':
s= Semaphore(4)for i in range(10):
t= Thread(target=func1,args=(s,))
t.start()
信號量
六.事件
## 事件#from threading import Thread,Event#e = Event() #e的狀態有兩種,False Ture,當事件對象的狀態為False的時候,wait的位置會阻塞#
#e.set() #將事件對象的狀態改為Ture#e.clear() #將事件對象的狀態改為False#print("在這里等待")#e.wait() #阻塞#print("還沒好")
View Code
七.隊列
mport queue#先進先出 FIFO#q=queue.Queue()#q.put('first')#q.put('second')#q.put('third')## q.put_nowait() #沒有數據就報錯,可以通過try來搞#print(q.get())#print(q.get())#print(q.get())## q.get_nowait() #沒有數據就報錯,可以通過try來搞
#'''#first#second#third#'''
#先進后出#import queue
#q = queue.LifoQueue() #隊列類似于棧,先進后出的順序#q.put('first')#q.put('second')#q.put('third')#q.put_nowait()
#print(q.get())#print(q.get())#print(q.get())## q.get_nowait() #沒有數據就報錯
#'''#third#second#first#'''
## 優先級隊列#import queue#q = queue.PriorityQueue()##put進入一個元祖,元祖的第一個元素是優先級(通常是數字,也可以是非數字之間的比較,數字越小優先級越高#q.put((-10,"a"))#q.put((-5,"a")) #負數也可以#
## q.put((20,'b')) #如果第一個參數數字的優先級一樣,那么按照后面的字符串acsii來排序## q.put((20,'c'))#
## q.put((20,{'a':11})) #TypeError: unorderable types: dict() < dict() 不能是字典## q.put((20,('w',1))) #優先級相同的兩個數據,他們后面的值必須是相同的數據類型才能比較,可以是元祖,也是通過元素的ascii碼順序來排序#
#print(q.get())#print(q.get())#"""結果:數字越小優先級越高,優先級高的優先出隊"""
View Code
八.線程池
concurrent.futures模塊提供了高度封裝的異步調用接口
ThreadPoolExecutor:線程池,提供異步調用
ProcessPoolExecutor: 進程池,提供異步調用
Both implement the same interface, whichis defined by the abstract Executor class.#2 基本方法#submit(fn, *args, **kwargs)
異步提交任務#map(func, *iterables, timeout=None, chunksize=1)
取代for循環submit的操作#shutdown(wait=True)
相當于進程池的pool.close()+pool.join()操作
wait=True,等待池內所有任務執行完畢回收完資源后才繼續
wait=False,立即返回,并不會等待池內的任務執行完畢
但不管wait參數為何值,整個程序都會等到所有任務執行完畢
submit和map必須在shutdown之前#result(timeout=None)
取得結果#add_done_callback(fn)
回調函數
#線程池#import time#from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor##ProcessPoolExecutor 進程池#from threading import current_thread#
#def func(n):#time.sleep(1)## print(n,current_thread().ident)#return n**2#if __name__ == '__main__':#t_p = ThreadPoolExecutor(max_workers = 4)#map_res = t_p.map(func,range(10)) #異步執行的,map自帶join功能#print(map_res)#print([i for i in map_res])
View Code
線程池的一些其他方法
#線程池的一些其他方法#import time#from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor#from threading import current_thread#def func(n):#time.sleep(1)##print(n,current_thread().ident)#return n**2#def func2(n):#print(n)#if __name__ == '__main__':#t_p = ThreadPoolExecutor(max_workers=4)#t_p_list = []#for i in range(10):#res_obj = t_p.submit(func, i) #異步提交了這10個任務## res_obj.result() #他和get一樣#t_p_list.append(res_obj)#t_p.shutdown() #close + join 等待全部完成之后關閉子線程,防止后面數據進入## print('t_res_list',t_p_list)#for e_res in t_p_list:#print(e_res.result())
View Code
九.回調函數
rom concurrent.futures importThreadPoolExecutorfrom threading importcurrent_threaddeffunc(n):
time.sleep(1)print(n**2)#print(n,current_thread().getName())
#return n**2
deffunc2(n):#print("current_thread>>>>",current_thread().getName())
print(n.result()) #result() 相當于 get()
if __name__ == '__main__':
t_p= ThreadPoolExecutor(max_workers=1)for i in range(3):
t_p.submit(func, i).add_done_callback(func2)print('主進程結束')
View Code
十.GIL鎖
#保證數據安全,鎖的是整個線程,每次只能有一個線程使用cpu,是CPython解釋器的特性
??
總結
以上是生活随笔為你收集整理的python线程代码_python--(十步代码学会线程)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 可变悬挂与空气悬挂的区别_可变悬架和空气
- 下一篇: python考核总结_Python阶段总