最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python探索之自定義實(shí)現(xiàn)線程池

 更新時(shí)間:2017年10月27日 15:05:17   作者:帶刺的Mary  
這篇文章主要介紹了Python探索之自定義實(shí)現(xiàn)線程池,使用queue實(shí)現(xiàn)線程池的方法,具有一定參考價(jià)值,需要的朋友可以了解下。

為什么需要線程池呢?

        設(shè)想一下,如果我們使用有任務(wù)就開啟一個(gè)子線程處理,處理完成后,銷毀子線程或等得子線程自然死亡,那么如果我們的任務(wù)所需時(shí)間比較短,但是任務(wù)數(shù)量比較多,那么更多的時(shí)間是花在線程的創(chuàng)建和結(jié)束上面,效率肯定就低了。

    線程池的原理:

        既然是線程池(Thread pool),其實(shí)名字很形象,就是把指定數(shù)量的可用子線程放進(jìn)一個(gè)"池里",有任務(wù)時(shí)取出一個(gè)線程執(zhí)行,任務(wù)執(zhí)行完后,并不立即銷毀線程,而是放進(jìn)線程池中,等待接收下一個(gè)任務(wù)。這樣內(nèi)存和cpu的開銷也比較小,并且我們可以控制線程的數(shù)量。

    線程池的實(shí)現(xiàn):

        線程池有很多種實(shí)現(xiàn)方式,在python中,已經(jīng)給我們提供了一個(gè)很好的實(shí)現(xiàn)方式:Queue-隊(duì)列。因?yàn)閜ython中Queue本身就是同步的,所以也就是線程安全的,所以我們可以放心的讓多個(gè)線程共享一個(gè)Queue。

        那么說到線程池,那么理應(yīng)也得有一個(gè)任務(wù)池,任務(wù)池中存放著待執(zhí)行的任務(wù),各個(gè)線程到任務(wù)池中取任務(wù)執(zhí)行,那么用Queue來實(shí)現(xiàn)任務(wù)池是最好不過的。

1.low版線程池

設(shè)計(jì)思路:運(yùn)用隊(duì)列queue

將線程類名放入隊(duì)列中,執(zhí)行一個(gè)就拿一個(gè)出來

import queue
import threading
class ThreadPool(object):
  def __init__(self, max_num=20):
    self.queue = queue.Queue(max_num) #創(chuàng)建隊(duì)列,最大數(shù)為20
    for i in range(max_num):
      self.queue.put(threading.Thread) #將類名放入隊(duì)列中
  def get_thread(self):
    return self.queue.get() #從隊(duì)列中取出類名
  def add_thread(self):
    self.queue.put(threading.Thread) #進(jìn)類名放入隊(duì)列中
def func(arg, p): #定義一個(gè)函數(shù)
  print(arg)
  import time
  time.sleep(2)
  p.add_thread()
pool = ThreadPool(10) #創(chuàng)建對(duì)象,并執(zhí)行該類的構(gòu)造方法,即將線程的類名放入隊(duì)列中
for i in range(30):
  thread = pool.get_thread() #調(diào)用該對(duì)象的get_thread方法,取出類名
  t = thread(target=func, args=(i, pool)) #創(chuàng)建對(duì)象,執(zhí)行func,參數(shù)在args中
  t.start()

由于此方法要求使用者修改原函數(shù),并在原函數(shù)里傳參數(shù),且調(diào)用方法也發(fā)生了改變,并且有空閑線程浪費(fèi)資源,實(shí)際操作中并不方便,故設(shè)計(jì)了下一版線程池。

2.絕版線程池

設(shè)計(jì)思路:運(yùn)用隊(duì)列queue

a.隊(duì)列里面放任務(wù)
b.線程一次次去取任務(wù),線程一空閑就去取任務(wù)

import queue
import threading
import contextlib
import time
StopEvent = object()
class ThreadPool(object):
  def __init__(self, max_num, max_task_num = None):
    if max_task_num:
      self.q = queue.Queue(max_task_num)
    else:
      self.q = queue.Queue()
    self.max_num = max_num
    self.cancel = False
    self.terminal = False
    self.generate_list = []
    self.free_list = []
  def run(self, func, args, callback=None):
    """
    線程池執(zhí)行一個(gè)任務(wù)
    :param func: 任務(wù)函數(shù)
    :param args: 任務(wù)函數(shù)所需參數(shù)
    :param callback: 任務(wù)執(zhí)行失敗或成功后執(zhí)行的回調(diào)函數(shù),回調(diào)函數(shù)有兩個(gè)參數(shù)1、任務(wù)函數(shù)執(zhí)行狀態(tài);2、任務(wù)函數(shù)返回值(默認(rèn)為None,即:不執(zhí)行回調(diào)函數(shù))
    :return: 如果線程池已經(jīng)終止,則返回True否則None
    """
    if self.cancel:
      return
    if len(self.free_list) == 0 and len(self.generate_list) < self.max_num:
      self.generate_thread()
    w = (func, args, callback,)
    self.q.put(w)
  def generate_thread(self):
    """
    創(chuàng)建一個(gè)線程
    """
    t = threading.Thread(target=self.call)
    t.start()
  def call(self):
    """
    循環(huán)去獲取任務(wù)函數(shù)并執(zhí)行任務(wù)函數(shù)
    """
    current_thread = threading.currentThread()
    self.generate_list.append(current_thread)
    event = self.q.get()
    while event != StopEvent:
      func, args, callback = event
      try:
        result = func(*args)
        success = True
      except Exception as e:
        success = False
        result = None
      if callback is not None:
        try:
          callback(success, result)
        except Exception as e:
          pass
      with self.worker_state(self.free_list, current_thread):
        if self.terminal:
          event = StopEvent
        else:
          event = self.q.get()
    else:
      self.generate_list.remove(current_thread)
  def close(self):
    """
    執(zhí)行完所有的任務(wù)后,所有線程停止
    """
    self.cancel = True
    count = len(self.generate_list)
    while count:
      self.q.put(StopEvent)
      count -= 1
  def terminate(self):
    """
    無論是否還有任務(wù),終止線程
    """
    self.terminal = True
    while self.generate_list:
      self.q.put(StopEvent)
    self.q.queue.clear()
  @contextlib.contextmanager
  def worker_state(self, state_list, worker_thread):
    """
    用于記錄線程中正在等待的線程數(shù)
    """
    state_list.append(worker_thread)
    try:
      yield
    finally:
      state_list.remove(worker_thread)
# How to use
pool = ThreadPool(5)
def callback(status, result):
  # status, execute action status
  # result, execute action return value
  pass
def action(i):
  print(i)
for i in range(30):
  ret = pool.run(action, (i,), callback)
time.sleep(3)
print(len(pool.generate_list), len(pool.free_list))
print(len(pool.generate_list), len(pool.free_list))
pool.close()
# pool.terminate()

總結(jié)

以上就是本文關(guān)于Python探索之自定義實(shí)現(xiàn)線程池的全部內(nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:python中模塊的__all__屬性詳解Python面向?qū)ο缶幊袒A(chǔ)解析(二)等,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!

相關(guān)文章

  • Python標(biāo)準(zhǔn)庫defaultdict模塊使用示例

    Python標(biāo)準(zhǔn)庫defaultdict模塊使用示例

    這篇文章主要介紹了Python標(biāo)準(zhǔn)庫defaultdict模塊使用示例,本文講解了如何使用defaultdict給字典value元素添加默認(rèn)類型以及defaultdict的兩個(gè)使用小案例,需要的朋友可以參考下
    2015-04-04
  • PyMongo進(jìn)行MongoDB查詢和插入操作的高效使用示例

    PyMongo進(jìn)行MongoDB查詢和插入操作的高效使用示例

    這篇文章主要為大家介紹了PyMongo進(jìn)行MongoDB查詢和插入操作的高效使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Pytest中skip skipif跳過用例詳解

    Pytest中skip skipif跳過用例詳解

    今天給大家?guī)淼氖顷P(guān)于Python的相關(guān)知識(shí),文章圍繞著Pytest中skip skipif跳過用例展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • python調(diào)用支付寶支付接口流程

    python調(diào)用支付寶支付接口流程

    這篇文章主要介紹了python調(diào)用支付寶支付接口流程,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-08-08
  • 基于Python實(shí)現(xiàn)人工智能算法的方法詳解

    基于Python實(shí)現(xiàn)人工智能算法的方法詳解

    Python已經(jīng)成為了機(jī)器學(xué)習(xí)領(lǐng)域最受歡迎的編程語言之一,Python的簡潔性和易用性使其成為了開發(fā)人員和數(shù)據(jù)科學(xué)家的首選語言,在本文中,我們將探討如何使用Python實(shí)現(xiàn)人工智能算法,感興趣的小伙伴跟著小編一起來探討吧
    2023-06-06
  • Java中重定向輸出流實(shí)現(xiàn)用文件記錄程序日志

    Java中重定向輸出流實(shí)現(xiàn)用文件記錄程序日志

    這篇文章主要介紹了Java中重定向輸出流實(shí)現(xiàn)用文件記錄程序日志,本文直接給出代碼實(shí)例,并對(duì)代碼做了詳細(xì)注解,需要的朋友可以參考下
    2015-06-06
  • python創(chuàng)建關(guān)聯(lián)數(shù)組(字典)的方法

    python創(chuàng)建關(guān)聯(lián)數(shù)組(字典)的方法

    這篇文章主要介紹了python創(chuàng)建關(guān)聯(lián)數(shù)組(字典)的方法,涉及Python操作字典的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-05-05
  • Python實(shí)現(xiàn)優(yōu)先級(jí)隊(duì)列結(jié)構(gòu)的方法詳解

    Python實(shí)現(xiàn)優(yōu)先級(jí)隊(duì)列結(jié)構(gòu)的方法詳解

    優(yōu)先級(jí)隊(duì)列(priority queue)是0個(gè)或多個(gè)元素的集合,每個(gè)元素都有一個(gè)優(yōu)先權(quán),接下來就來看一下簡潔的Python實(shí)現(xiàn)優(yōu)先級(jí)隊(duì)列結(jié)構(gòu)的方法詳解:
    2016-06-06
  • 簡單介紹Python中的JSON使用

    簡單介紹Python中的JSON使用

    這篇文章主要介紹了Python中的JSON使用,示例代碼基于Python2.x版本,需要的朋友可以參考下
    2015-04-04
  • Django 簡單實(shí)現(xiàn)分頁與搜索功能的示例代碼

    Django 簡單實(shí)現(xiàn)分頁與搜索功能的示例代碼

    這篇文章主要介紹了Django 簡單實(shí)現(xiàn)分頁與搜索功能的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11

最新評(píng)論

启东市| 义马市| 忻城县| 峨眉山市| 连山| 京山县| 平舆县| 疏勒县| 弋阳县| 任丘市| 阳谷县| 高邮市| 项城市| 盐源县| 康定县| 塘沽区| 建始县| 腾冲县| 大理市| 贡嘎县| 哈巴河县| 驻马店市| 新蔡县| 德安县| 景德镇市| 固始县| 绥宁县| 武宁县| 长汀县| 湘潭县| 厦门市| 蚌埠市| 七台河市| 丰镇市| 普格县| 建平县| 那曲县| 开封县| 肥乡县| 孟津县| 江安县|