多線程併發

更簡單的線程池: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():
     #....  寫入文件,輸出最終結果

#注意:能夠在任意一層函數設置
相關文章
相關標籤/搜索