<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      python進階(七)~~~多線程并發

       一、并發和并行

      并發:任務數>CPU核數,通過系統的各任務調度算法,來回切換,實現多個任務“一起”運行,實際上不是真正同時一起運行,只是切換運行的速度相當快,看上去是一起執行的而已;

      并行:任務數<=CPU核數,是真正的一起同時運行。

      同步:同步是指代碼調用IO操作時,必須等待IO操作完成返回才調用的方式,只有一個主線;

      異步:異步是指代碼調用IO操作時,不必等待IO操作完成返回才調用的方式,存在多條主線;

      from threading import Thread
      import time
      
      def timer(fun):
          def wrapper(*args,**kwargs):
              time1 = time.time()
              fun(*args,**kwargs)
              time2=time.time()
              print("當前函數運行時間為:{}".format(time2-time1))
              return time2-time1
          return wrapper
      
      def work1():
         for i in range(6):
              time.sleep(1)
              print(f'第{i}次澆花中')
      
      def work2(name):
         for i in range(5):
              time.sleep(1)
              print(f'第{i}次{name}打墻中')
      
      # 同步運行如下,需用11s多
      @timer
      def main():
          work1()
          work2() 
      
      #異步運行,只用6s多
      @timer
      def main2():
          t1=Thread(target=work2,args=('musen',))  # 線程執行函數的傳參或者 Thread(target=work2,kwargs={'name':'musen'}) 這種方式傳參
       t1.start() # 初始新線程的準備工作并執行,不一定在主線程后執行,也有可能先于主線程 print("打墻任務異步執行中") work1() main() main2()

      threading模塊講解:

      創建線程對象: t1=threading.Thread(target=func)    func為指定線程執行的任務函數

      Thread類常用方法、屬性

      1.start() :啟動線程活動。
      2.run():這個方法描述線程的活動,可以在子類中覆蓋這個方法。
      3.join(timeout=None):設置主線程等待子線程執行結束后再繼續運行??梢栽O定一個timeout參數,避免無休止的等待。因為兩個線程順序完成,看起來象一個線程,所以稱為線程的合并.
      通過傳給join一個參數來設置超時,也就是超過指定時間join就不在阻塞進程。而在實際應用測試的時候發現并不是所有的線程在超時時間內都結束的,而是順序執行檢驗是否在time_out時間內超時,例如,超時時間設置成2s,前面一個線程在沒有完成的情況下,后面線程執行join會從上一個線程結束時間起再設置2s的超時。
      4.name:線程名
      5.getname(): 返回線程名
      6.setname(): 設置線程名
      7.ident:線程的標識符
      8.is_alive(): 返回線程是否活動
      9.daemon:布爾值,表示這個線程是否是守護線程

      threading.active_count():這個函數返回當前線程的個數,這個程序的值也等于列表 

      threading.current_thread():返回當前的線程對象

      threading.enumereate():返回當前運行線程的列表

      threading.main_thread():返回主線程,正常情況下,主線程就是python 解釋器運行時開始的那個線程。

      # 定義線程類
      import
      time from threading import Thread def timer(fun): def wrapper(*args,**kwargs): time1 = time.time() fun(*args,**kwargs) time2=time.time() print("當前函數運行時間為:{}".format(time2-time1)) return time2-time1 return wrapper class MyTread(Thread):
         def __init__(self):
          super().__init__(*args,**keargs)
          self.url=url
      def run(self): headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 afari/537.36"} for i in range(100): #res=requests.get('https://www.baidu.com',headers=headers)
           res=requests.get(url=self.url,headers=headers) 
      print(res) @timer def main(): t_list=[] for i in range(10): #t=MyTread()
           t=MyTread('https://www.baidu.com') t.start()
      #t.join() 如果放在這里,就會變成單線程運行,一個執行完再建一個子線程 # 遍歷所有子線程,設置子線程全部執行完后再執行主線程 for j in t_list: j.join() if __name__=="__main__": main()

      多線程可以共享全局變量(使用同一塊內存),修改會造出資源競爭,因此python同一進程里的多線程不可能實現并行,只能是并發,在線程中來回切換。

      線程之間哪些操作會引起切換?

      1. IO耗時操作:網絡、文件、輸入等耗時的IO操作,會自動進行線程切換;

      2. 線程執行時間達到一定的閥值時會執行切換;

      100萬bug的解決方法:

      1. 通過加鎖來處理

      2. 通過存儲隊列來做

      from threading import Thread,Lock
      
      num=0
      
      def work1():
      global num
      for i in range(1000000): meta.acquire() # 加鎖 num+=1 meta .release() # 解鎖 def work2():
         global num
      for i in range(1000000): meta.acquire() # 加鎖 num+=1 meta .release() # 解鎖 meta=Lock() # 創建一把鎖 def main(): t1=Thread(target=work1) t2=Thread(target=work2) t1.start() t2.start() t1.join() t2.join() print(num) if __name__=='__main__': main()

      GIL全局解釋器鎖:

      IO密集型任務: CPU占用少,大部分時間在IO操作等待上。這種適合多線程來完成

      CPU密集型任務:CPU占用多,需要進行大量的計算。這種適合單線程來完成。

      關于GIL的幾點說明:

      1.python語言和GIL沒有關系,僅僅是由于歷史原因在Cpython虛擬機(解釋器)上,難以移除GIL;

      2.GIL:全局解釋器鎖,每個線程在執行中都需要先獲取GIL,保證同一時刻只有一個線程可以執行代碼;

      3. 線程釋放GIL鎖的情況,在IO等操作可能引起阻塞的system call之前,可以暫時釋放GIL,執行完畢后必須獲取GIL,python3使用計時器執行時間達到閥值時(python2使用tickets記數達到100)當前線程釋放GIL

      4. python多進程可以使用多核的CPU資源

      死鎖:

      在多線程中,線程可以通過互斥鎖來保證對同一資源的唯一占有,但當程序變得復雜后,可能會出現線程 A 對資源 A 上了鎖,而線程 A 后邊需要用到資源 B,使用完畢后才會對資源 A解鎖,而線程 B 對資源 B 上了鎖,它后邊選要用到資源 A,用過后才會給 B 解鎖,如果線程 A 和線程 B 同時運行,就可能會造成一種情況:線程 A 在等待線程 B 解鎖,線程 B 也在等待線程 A 解鎖,這就是死鎖問題。

      解決方法:? 死鎖問題應該盡量在設計程序時避免,或添加等待超時時間,從而檢測程序是否產生了死鎖,另一種就是通過銀行家算法也可以避免死鎖問題

      銀行家算法:? 銀行家算法的思想就是,假設銀行有 10 元,這個時候有三個人提出貸款,A 要貸款 9 元,B 要貸款 3 元,C 要貸款 8 元,這時,銀行肯定不夠將所有人都滿足,銀行家算法就誕生了

      ? 這時銀行為了留住所有客戶并且保證自己的錢不會不足,便分批貸款給客戶,先借給 A 2 元、B 2 元、C 4 元,銀行還剩 2 元,此時 B 直需要再借 1 元就滿足了他自己的需求,銀行便借給他 1 元,自己剩 1 元,當 B 用完,將 3 元還給銀行后,銀行再將這 4 元借給 C,C 也就滿足了,等 C 還款后,再將 8 元中的 7 元借給 A,這樣便動態的滿足了三個客戶的需求

      ? 銀行家算法在程序中實際上也是模擬了銀行貸款的過程,操作系統會動態的向各個線程分配資源,在分配前,系統會判斷分配后會不會導致系統進入不安全狀態,不會就分配資源給線程,會則令線程等待

      posted @ 2020-02-10 00:40  青域  閱讀(591)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚欧洲乱码视频一二三区| 99国精品午夜福利视频不卡99| 日韩av一区二区三区精品| 日韩乱码人妻无码中文字幕视频| 亚洲国产中文字幕在线视频综合| 乱码视频午夜在线观看| 国产亚洲精品VA片在线播放| 夜色福利站WWW国产在线视频| 在线观看国产区亚洲一区| 嗯灬啊灬把腿张开灬动态图| 大屁股国产白浆一二区| 国产超碰人人做人人爰| 亚洲精品色一区二区三区| 伊人精品无码av一区二区三区| 久久成人 久久鬼色| 亚洲av成人免费在线| 一区二区三区精品不卡| 国产地址二永久伊甸园| 国产乱女乱子视频在线播放| 亚洲第一香蕉视频啪啪爽| 亚洲男人电影天堂无码| 亚洲国产色播AV在线| 亚洲三级香港三级久久| 冀州市| 久久夜色精品国产噜噜亚洲sv| 狠狠综合久久综合88亚洲| 临清市| 特级做a爰片毛片免费看无码| 中文字幕精品人妻av在线| 看亚洲黄色不在线网占| 妖精视频亚州无吗高清版| 国产伦精品一区二区三区妓女下载| 亚洲情色av一区二区| 97久久精品无码一区二区| 国产麻豆9l精品三级站| 亚洲最大福利视频网| 国产日韩精品一区二区在线观看播放| 国产精品一区在线蜜臀| 亚洲精品三区四区成人少| 国产精品国产精品偷麻豆| 中国性欧美videofree精品|