更簡單的線程池:python
多線程和多進程均可以很容易的實現併發,協程經過切換上下文來充分利用cpu實現併發效果
threading模塊
多線程
Thread類的基本狀態和行爲
屬性名和值:併發
name=None,group=None,target=None,args=(),kwargs={},daemon=None
方法:異步
start(),join(),run(), join()
使主線程等待使用join()方法的子進程結束,不然阻塞本身 ,
Thread中的子進程默認daemon就是None,這意味着子進程不結束,主進程也不結束,說明主進程是個好大哥,
而thread模塊開啓的子進程就沒這個命,主進程結束,子進程跟着完蛋。
join()方法:
效果 :使主線程等待使用join()方法的子線程結束,不然阻塞本身 ,
使用場景:主線程須要接受子線程的計算結果時使用
守護線程是指不重要的進程,若是Thread實例化子進程的時候將其設置成守護進程,主線程結束時,將結束子線程。函數
子進程的建立與運行,分爲三種方式,測試
-實例化Thread,target=自定義函數ui
-實例化Thread,target=自定義類,start()這個實例時,自動調用自定義類的__call__()方法,因此,自定義類必需要自定義__call__()方法。spa
-自定義建立一個Thread的派生子類,而後自定義其run()方法,而後實例化這個類,而後調用其start()方法,
-須要注意,實例化子進程使用一次,不能再次調用start()方法線程
主要使用第一種方法,和第三種方法code
給出第三種方法的例子
import time, threading import threading,time class Mythread(threading.Thread): def __init__(self,args): threading.Thread.__init__(self) self.args=args def do_1(self): print('我是do_1 我是作好事') def do_2(self): print('我是do_2 我是作傻事') def do_3(self): print('我是do_3 我是作壞事') def run(self): time.sleep(1) if self.args % 3==0: self.do_1() if self.args % 3==1: self.do_2() if self.args % 3==2: self.do_3() if __name__ == '__main__': for i in range(20): t = Mythread(i) t.start() print('大哥已經完事,等小弟們') 運行結果:
大哥已經完事,等小弟們
我是do_2 我是作傻事
我是do_1 我是作好事
我是do_3 我是作壞事
我是do_1 我是作好事
我是do_2 我是作傻事
我是do_3 我是作壞事
我是do_1 我是作好事
我是do_1 我是作好事
我是do_2 我是作傻事
我是do_2 我是作傻事
我是do_3 我是作壞事
我是do_1 我是作好事
我是do_3 我是作壞事
我是do_2 我是作傻事
我是do_3 我是作壞事
我是do_2 我是作傻事
我是do_1 我是作好事
我是do_2 我是作傻事
我是do_3 我是作壞事
我是do_1 我是作好事
類方法:
active_count():存活的線程數量,能夠用來控制同時存活併發線程數目。通過測試,win10,i7四核線程能夠同時發起幾千個線程,固然這沒有必要。
current_thread():返回當前環境的Thread對象,數據類型int
enumerate():返回活動的Thread對象列表,數據類型list
[<_MainThread(MainThread, started 28388)>, <Mythread(Thread-1, started 21276)>, <Mythread(Thread-2, started 29028)>, <Mythread(Thread-3, started 29528)>, <Mythread(Thread-4, started 19448)>, <Mythread(Thread-5, started 26416)>, <Mythread(Thread-6, started 22084)>, <Mythread(Thread-7, started 31032)>, <Mythread(Thread-8, started 24824)>, <Mythread(Thread-9, started 14076)>, <Mythread(Thread-10, started 31076)>, <Mythread(Thread-11, started 22516)>, <Mythread(Thread-12, started 30032)>, <Mythread(Thread-13, started 22836)>, <Mythread(Thread-14, started 19340)>, <Mythread(Thread-15, started 27456)>, <Mythread(Thread-16, started 31292)>, <Mythread(Thread-17, started 26192)>, <Mythread(Thread-18, started 22444)>, <Mythread(Thread-19, started 25536)>, <Mythread(Thread-20, started 30204)>]
setprofile(func):爲全部進程設置一個trace函數
setprofile(func):爲全部線程設置一個profile函數
stack_size(size=0):返回新建立線程的棧大小,設定以後建立線程的棧大小
鎖和信號量,控制數據訪問
信號量用來控制併發子線程的數量,使其不至於訪問過快,
信號量是一個計數器 設置它的最大值,最小值不設置,爲0,
bignumber=BoundedSemaphore(5) 表明最大數字是5,每一次bignumber.acquire()使數字減一,
bigunmber.release()使數字加一 當數字小於0,或者大於5時阻塞。
acquire()和release方法參數: acquire(self, blocking=True, timeout=None):
register函數
-對主進程運行時間的控制,
- 在子進程異步執行同時,主程序後續執行依賴子程序的返回結果
join(),atexit模塊register。
實現較爲精細的控制:join方法經過註冊每個子線程,當即阻塞主線程
粗暴的控制:
from atexit import register #在當前函數租冊一個退出函數,當前函數退出的時候執行 @register def _atexit(): #.... 寫入文件,輸出最終結果 #注意:能夠在任意一層函數設置