Python-信號量和線程池-semaphore ThreadPollExector

信號量python

  其實本質上是鎖,Lock是單鎖,信號量是指定多把鎖,也就是說經過信號量指定多個數線程能夠訪問相同資源,通常狀況下讀操做能夠有多個,但寫操做同時只有一個dom

 

信號量模塊  semaphoreui

  # 使用起來和普通鎖沒 什麼區別,但這個是比鎖更加粗粒度鎖,鎖的是線程spa

  # 在線程實例前加鎖,把鎖傳遞進線程,在線程結束時候釋放鎖線程

from threading import Thread, Semaphore
from queue import Queue


def add(chan, sem_lock):
    for i in range(10):
        chan.put(i)
    # 釋放鎖
    sem_lock.release()


if __name__ == '__main__':
    numbers = Queue()
    # 申明信號量
    sem_lock = Semaphore(4)
    sem_lock.acquire()
    # 把鎖傳遞進線程
    tasks = {Thread(target=add, args=(numbers, sem_lock), name="北門吹雪 %s" % i) for i in range(10)}
    for task in tasks:
        task.start()
    for task in tasks:
        task.join()
    print(numbers.get())

  

線程池對象

  不單單是數量控制,能夠獲取線程狀態、任務狀態、線程返回值等信息blog

  線程池模塊  ThreadPollExecutor接口

 

線程池使用過程資源

  1. 實例化線程池get

  2. 提交任務,會有個返回對象,submit是不會堵塞,當即返回

  3. 讓主線程等待線程執行完成

  4. 關閉線程池

 

獲取狀態信息  線程對象

  1. 判斷是否執行完        .done()

  2. 獲取任務執行結果,堵塞    .result()

  3. 取消任務            .cancle()

 

對多個線程列表獲取結果  線程對象

  1. as_complated        獲取已經執行完成的線程結果

def add(number, name):
    sum = 0
    for i in range(number):
        sum += i
    # 模擬個線程執行堵塞狀況
    time.sleep(random())
    # 返回線程執行結果
    return sum


if __name__ == '__main__':
    thread_pool = ThreadPoolExecutor(max_workers=3)
    print("北門吹雪:http://www.cnblogs.com/2bjiujiu/")
    name = "北門吹雪"
    tasks = {thread_pool.submit(add, randint(10, 20), name) for _ in range(20)}

    # map方法和as_completed最大區別在於map變化的只是參數線程是同一個線程,而as_completed能夠執行不一樣的線程任務
    for data in thread_pool.map(add, {randint(10, 20) for _ in range(20)}):
        print(data)

  2. map            直接返回線程執行結果,保持傳遞進去順序

def add(number):
    sum = 0
    for i in range(number):
        sum += i
    # 模擬個線程執行堵塞狀況
    time.sleep(random())
    # 返回線程執行結果
    return sum


if __name__ == '__main__':
    print("北門吹雪")
    thread_pool = ThreadPoolExecutor(max_workers=3)
    tasks = {thread_pool.submit(add, randint(10, 20)) for _ in range(20)}

    # map方法和as_completed最大區別在於map變化的只是參數線程是同一個線程,而as_completed能夠執行不一樣的線程任務
    for data in thread_pool.map(add, {randint(10, 20) for _ in range(20)}):
        print(data)

  3. wait          等待全部線程執行完成

from concurrent.futures import ThreadPoolExecutor, as_completed, wait
from random import randint, random
import time


def add(number):
    sum = 0
    for i in range(number):
        sum += i
    # 模擬個線程執行堵塞狀況
    time.sleep(random())
    # 返回線程執行結果
    return sum


if __name__ == '__main__':
    thread_pool = ThreadPoolExecutor(max_workers=3)
    tasks = {thread_pool.submit(add, randint(10, 20)) for _ in range(20)}
print("北門吹雪") # 主線程等待全部子線程執行完,不須要結果 # wait(tasks)
北門吹雪:http://www.cnblogs.com/2bjiujiu/

經驗:

  1. 線程池和信號量在某種程度如容許執行的線程數效果上是同樣,但線程池能夠獲取線程執行結果獲得線程執行狀態

  2. 使用線程池須要首先實例化,而後提交線程,返回線程對象,而後在主線程中選擇獲取結果或者不須要結果,也能夠選擇堵塞等待線程執行完或不等待線程執行完

  3. 獲取線程執行結果,能夠參照Go語言中CSP通訊模式,我的以爲這是個很是好的解決方案,這樣的線程池接口提交遠比CSP通訊來的複雜

北門吹雪:http://www.cnblogs.com/2bjiujiu/
相關文章
相關標籤/搜索