手寫乙個執行緒池類

2021-10-23 05:10:17 字數 2806 閱讀 6095

執行緒池是多執行緒的一種處理方式,使用者只需要把需要執行的任務放到執行緒池中,不用關心哪個執行緒執行了任務,執行緒會搶占並執行該任務,當執行緒有空閒的時候,就會去等待佇列裡檢視是否還有排隊等待的任務,如果有,就會佇列中取出任務並繼續執行。如果沒有,執行緒就會進入休眠。

接下來我們會建立乙個執行緒池管理類,建立時只需要指定執行緒數量,執行任務時將任務放入執行緒池中即可。

import threading

import queue

import time

import datetime

這裡需要提醒的一點是,我們在開啟執行緒物件的時候必須要設定守護模式,如果不設定主線程就會一直等待子執行緒結束,如果執行緒池為空,也就是無任務的時候佇列的get會一直阻塞,子執行緒不會結束,那麼程式無法結束。

class

threadpool

:"""

主要是配合佇列來進行實現, 我們定義好乙個佇列物件, 然後將我們的任務物件put到我們的佇列物件中.

任何使用多執行緒, 讓我們的執行緒去get佇列中的物件, 然後各自去執行自己get到的任務,

這樣的話其實也就實現了執行緒池

"""def__init__

(self, n)

:"""

構造乙個指定數量執行緒的執行緒池.

:param n: 執行緒數量

"""self.queue_obj = queue.queue(

)for i in

range

(n):

# 開啟執行緒物件

threading.thread(target=self.worker, daemon=

true

).start(

)def

worker

(self)

:"""

執行緒物件, 寫while true是為了能夠一直去執行任務.

:return: none

put一次計數器+1

task_done一次計數器-1

join根據計數器為準, 如果不為0就阻塞

"""while

true

: func = self.queue_obj.get(

)# 當task_done執行後讓計數器為0了, 那join就不阻塞

# join不阻塞意味著func還沒執行完主線程就結束了.

func(

) self.queue_obj.task_done(

)def

(self, func)

:"""

向佇列中傳入的需要執行的函式物件.

:param func: 函式物件

:return: none

"""self.queue_obj.put(func)

defjoin

(self)

:"""

等待佇列中的內容被取完.

:return: none

"""self.queue_obj.join(

)

測試函式

def

task1()

: time.sleep(2)

print

('task1 over'

)def

task2()

: time.sleep(3)

print

('task2 over'

)

執行緒池的使用

if __name__ ==

'__main__'

: p = threadpool(4)

print

('開始時間為:'

, datetime.datetime.now())

# 如果get傳送阻塞意味著隊列為空, 隊列為空意味著join不阻塞, join不阻塞意味著print('結束時間為:')會執行

# print('結束時間為:')會執行意味著主線程沒事情做了, 主線程沒事情做了意味著主線程結束

# 主線程結束意味著不等待設定了守護的執行緒, 不等待意味著子執行緒會隨著主線程的死亡而死亡(這就是為什麼要設定守護模式的原因)

# 如果沒有設定守護模式, get發生阻塞意味著子執行緒任務執行不完 子執行緒任務執行不完意味著主線程一直要等子執行緒完成.

# 主線程一直要等子執行緒完成任務意味著這個程式一直都結束不了 程式一直都結束不了意味著這個程式有毒.

# 主線程等待子執行緒把任務從佇列中取完.

# 子執行緒把任務拿走, 什麼時候做完也只是時間問題而已, 而且這個時間問題和主線程沒關係.

p.join(

)print

('結束時間為:'

, datetime.datetime.now(

))

以上程式的執行結果如下:

開始時間為: 2020-04

-1019:

11:31.275047

task1 over

task1 over

task2 over

task2 over

task2 over

task2 over

task1 over

task1 over

結束時間為: 2020-04

-1019:

11:36.277253

執行緒池的使用無疑提高了程式的執行效率,而且不會對系統造成較大的開銷,執行緒池的最大執行緒數取決於cpu的核心數量,是有上限的。

以上就是博主今天給大家分享的內容了,希望大家能夠有所收穫,最後祝大家學習進步!

實現乙個執行緒池

一.執行緒最主要的三個同步機制 1.訊號量 2.互斥鎖 3.條件變數 二.對三個同步機制分別實現乙個包裝類 ifdef locker h define locker h include include 訊號量的封裝 class sem sem bool wait bool post private ...

執行緒池(一) 實現乙個簡單的執行緒池

我們知道頻繁的建立 銷毀執行緒是不可取的,為了減少建立和銷毀執行緒的次數,讓每個執行緒可以多次使用,我們就可以使用執行緒池,可以降低資源到的消耗。執行緒池裡面肯定有多個執行緒,那麼我們就簡單的用乙個陣列來儲存執行緒,那我們我們預設裡面有 5 個執行緒。那我們執行緒池裡只有五個執行緒能同時工作,那同時...

執行緒池 如何正確的配置乙個執行緒池

我們在建立自己的執行緒池時,會時常因為不知道給核心執行緒數或者最大執行緒數設定多少為好,其實這個時需要看你的執行緒池的使用場景和伺服器cup的配置,根據這些前置條件,我們再去判斷如何去設定合適的執行緒數,並不是我們想設定多少執行緒數大小就可以設定多少,這樣可能會導致執行緒發揮不到最大的效能,甚至還有...