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/
相关文章
相关标签/搜索