信号量

  其实本质上是锁,Lock是单锁,信号量是指定多把锁,也就是说通过信号量指定多个数线程可以访问相同资源,一般情况下读操作可以有多个,但写操作同时只有一个

信号量模块  semaphore

  # 使用起来和普通锁没 什么区别,但这个是比锁更加粗粒度锁,锁的是线程

  # 在线程实例前加锁,把锁传递进线程,在线程结束时候释放锁

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())

  

线程池

  不仅仅是数量控制,可以获取线程状态、任务状态、线程返回值等信息

  线程池模块  ThreadPollExecutor

线程池使用过程

  1. 实例化线程池

  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/

Python-信号量和线程池-semaphore ThreadPollExector的更多相关文章

  1. python day 20: 线程池与协程,多进程TCP服务器

    目录 python day 20: 线程池与协程 2. 线程 3. 进程 4. 协程:gevent模块,又叫微线程 5. 扩展 6. 自定义线程池 7. 实现多进程TCP服务器 8. 实现多线程TCP ...

  2. Python 多线程和线程池

    一,前言 进程:是程序,资源集合,进程控制块组成,是最小的资源单位 特点:就对Python而言,可以实现真正的并行效果 缺点:进程切换很容易消耗cpu资源,进程之间的通信相对线程来说比较麻烦 线程:是 ...

  3. 『Python』 ThreadPool 线程池模板

    Python 的 简单多线程实现 用 dummy 模块 一句话就可以搞定,但需要对线程,队列做进一步的操作,最好自己写个线程池类来实现. Code: # coding:utf-8 # version: ...

  4. python爬虫之线程池和进程池

    一.需求 最近准备爬取某电商网站的数据,先不考虑代理.分布式,先说效率问题(当然你要是请求的太快就会被封掉,亲测,400个请求过去,服务器直接拒绝连接,心碎),步入正题.一般情况下小白的我们第一个想到 ...

  5. python小demo-01: 线程池+多进程实现cpu密集型操作

    起因: 公司有一个小项目,大概逻辑如下: 服务器A会不断向队列中push消息,消息主要内容是视频的地址,服务器B则需要不断从队列中pop消息,然后将该视频进行剪辑最终将剪辑后的视频保存到云服务器.个人 ...

  6. 【Python】多线程-线程池使用

    1.学习目标 线程池使用 2.编程思路 2.1 代码原理 线程池是预先创建线程的一种技术.线程池在还没有任务到来之前,创建一定数量的线程,放入空闲队列中.这些线程都是处于睡眠状态,即均为启动,不消耗 ...

  7. Python之路——线程池

    1 线程基础 1.1 线程状态 线程有5种状态,状态转换的过程如下图所示: 1.2 线程同步——锁 多线程的优势在于可以同时运行多个任务(至少感觉起来是这样,其实Python中是伪多线程).但是当线程 ...

  8. python爬虫14 | 就这么说吧,如果你不懂python多线程和线程池,那就去河边摸鱼!

    你知道吗? 在我的心里 你是多么的重要 就像 恩 请允许我来一段 freestyle 你们准备好了妹油 你看 这个碗 它又大又圆 就像 这条面 它又长又宽 你们 在这里 看文章 觉得 很开心 就像 我 ...

  9. Python爬虫之线程池

    详情点我跳转 关注公众号"轻松学编程"了解更多. 一.为什么要使用线程池? 对于任务数量不断增加的程序,每有一个任务就生成一个线程,最终会导致线程数量的失控,例如,整站爬虫,假设初 ...

随机推荐

  1. JS学习阶段性总结-1

    各种函数的声明 /** * 函数的声明 */ // 声明一个方法,任意调用 function aaa(args){...} // 声明一个函数并以变量的形式展示出去,因此无法再声明前调用 var fn ...

  2. Bellman-Ford算法 例题:P3371 单源最短路径

    看到还没人用Bellman-Ford过,赶紧水一发 lz非常弱,求各位大佬轻喷qwq 洛谷题目传送门:P3371 0."松弛"操作 如果存在一条边\((u,v)\)通过中继的方式可 ...

  3. el-table表头v-for循环遇到的问题

    这两天在项目中遇到了el-table表头需要动态变化,也就是点击不同的标签显示对应的表格,主要表头都不一样,那么表格也就是动态的,表头也需要循环 一开始以为很简单 <el-table       ...

  4. 总结回顾js arr的常见方法以及相关的使用场景(一)

    Array对象方法 1.arr.concat() 连接两个或更多的数组,并返回结果. 连接数组中的值 连接两个数组 连接三个数组 2.arr.join() 把数组的所有元素放入一个字符串.元素通过指定 ...

  5. 如何自制WC3地形纹理贴图

    http://world-editor-tutorials.thehelper.net/tilesets.php https://wenku.baidu.com/view/e761c953cc1755 ...

  6. .Net在Windows上使用Jenkins做CI/CD的那些事

    背景 最近入职了一家新公司,公司各个方面都让我非常的满意,我也怀着紧张与兴奋的心情入职后,在第一天接到了领导给我的第一个任务——把整个项目的依赖引用重新整理并实施项目的CI/CD. 本篇的重点主要分享 ...

  7. 知识点干货——CSS动画

    CSS动画 (transition.animation) //2D动画 transform:translate(); /*偏移*/ transform:rotate(); /*旋转角度*/ trans ...

  8. 给EmpMapper开放Restful接口

    本文例程下载:https://files.cnblogs.com/files/xiandedanteng/gatling20200428-3.zip 接口控制器代码如下: 请求url和响应都写在了每个 ...

  9. AMQP 概论

    AMQP 是应用层协议的一个开放标准,为面向消息的中间件设计.基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制.目标是实现一种在全行业广泛使用的标准消 ...

  10. SpringBoot版不需要配置文件注解获取当前登录用户

    本文讯(2019年3月30日 飞快的蜗牛博客)   我是一个懒人,很久不写博客,想起来看到也不一定会写,只有心血来潮的时候写写,"钱塘江上潮信来,今日方知我是我"...... 空杯 ...