中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python程序中的線程操作 concurrent模塊使用詳解

發布時間:2020-09-24 07:27:30 來源:腳本之家 閱讀:222 作者:Cecilia喜陳 欄目:開發技術

一、concurrent模塊的介紹

concurrent.futures模塊提供了高度封裝的異步調用接口

ThreadPoolExecutor:線程池,提供異步調用

ProcessPoolExecutor:進程池,提供異步調用

ProcessPoolExecutorThreadPoolExecutor:兩者都實現相同的接口,該接口由抽象Executor類定義。

二、基本方法

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) :回調函數

三、進程池和線程池

池的功能:限制進程數或線程數.

什么時候限制: 當并發的任務數量遠遠大于計算機所能承受的范圍,即無法一次性開啟過多的任務數量 我就應該考慮去限制我進程數或線程數,從保證服務器不崩.

3.1 進程池

from concurrent.futures import ProcessPoolExecutor
from multiprocessing import Process,current_process
import time
def task(i):
  print(f'{current_process().name} 在執行任務{i}')
  time.sleep(1)
if __name__ == '__main__':
  pool = ProcessPoolExecutor(4) # 進程池里又4個進程
  for i in range(20): # 20個任務
    pool.submit(task,i)# 進程池里當前執行的任務i,池子里的4個進程一次一次執行任務

3.2 線程池

from concurrent.futures import ThreadPoolExecutor
from threading import Thread,currentThread
import time
def task(i):
  print(f'{currentThread().name} 在執行任務{i}')
  time.sleep(1)
if __name__ == '__main__':
  pool = ThreadPoolExecutor(4) # 進程池里又4個線程
  for i in range(20): # 20個任務
    pool.submit(task,i)# 線程池里當前執行的任務i,池子里的4個線程一次一次執行任務

四、Map的用法

from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import os,time,random
def task(n):
  print('%s is runing' %os.getpid())
  time.sleep(random.randint(1,3))
  return n**2
if __name__ == '__main__':
  executor=ThreadPoolExecutor(max_workers=3)
  # for i in range(20):
  #   future=executor.submit(task,i)
  executor.map(task,range(1,21)) #map取代了for+submit

五、同步和異步

理解為提交任務的兩種方式

同步: 提交了一個任務,必須等任務執行完了(拿到返回值),才能執行下一行代碼

異步: 提交了一個任務,不要等執行完了,可以直接執行下一行代碼.

同步:相當于執行任務的串行執行

異步

from concurrent.futures import ProcessPoolExecutor
from multiprocessing import Process,current_process
import time
n = 1
def task(i):
  global n
  print(f'{current_process().name} 在執行任務{i}')
  time.sleep(1)
  n += i
  return n
if __name__ == '__main__':
  pool = ProcessPoolExecutor(4) # 進程池里又4個線程
  pool_lis = []
  for i in range(20): # 20個任務
    future = pool.submit(task,i)# 進程池里當前執行的任務i,池子里的4個線程一次一次執行任務
    # print(future.result()) # 這是在等待我執行任務得到的結果,如果一直沒有結果,這里會導致我們所有任務編程了串行
                # 在這里就引出了下面的pool.shutdown()方法
    pool_lis.append(future)
  pool.shutdown(wait=True) # 關閉了池的入口,不允許在往里面添加任務了,會等帶所有的任務執行完,結束阻塞
  for p in pool_lis:
    print(p.result())
  print(n)# 這里一開始肯定是拿到0的,因為我只是去告訴操作系統執行子進程的任務,代碼依然會繼續往下執行
  # 可以用join去解決,等待每一個進程結束后,拿到他的結果

六、回調函數

import time
from threading import Thread,currentThread
from concurrent.futures import ThreadPoolExecutor
def task(i):
  print(f'{currentThread().name} 在執行{i}')
  time.sleep(1)
  return i**2

# parse 就是一個回調函數
def parse(future):
  # 處理拿到的結果
  print(f'{currentThread().name} 結束了當前任務')
  print(future.result())
if __name__ == '__main__':
  pool = ThreadPoolExecutor(4)
  for i in range(20):
    future = pool.submit(task,i)
    '''
    給當前執行的任務綁定了一個函數,在當前任務結束的時候就會觸發這個函數(稱之為回調函數)
    會把future對象作為參數傳給函數
    注:這個稱為回調函數,當前任務處理結束了,就回來調parse這個函數
    '''
    future.add_done_callback(parse)
    # add_done_callback (parse) parse是一個回調函數
    # add_done_callback () 是對象的一個綁定方法,他的參數就是一個函數

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

舟曲县| 五河县| 大同县| 武功县| 汉源县| 慈利县| 珲春市| 阜城县| 砚山县| 鸡西市| 海盐县| 云安县| 介休市| 神农架林区| 嘉禾县| 那坡县| 策勒县| 搜索| 兰西县| 开鲁县| 东明县| 湟中县| 南开区| 民和| 邳州市| 高唐县| 兰溪市| 大石桥市| 龙胜| 蕉岭县| 漳浦县| 公主岭市| 长春市| 元江| 霍邱县| 马鞍山市| 日土县| 莱阳市| 玉溪市| 巩义市| 日喀则市|