Python-信号量和线程池-semaphore ThreadPollExector
信号量
其实本质上是锁,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的更多相关文章
- python day 20: 线程池与协程,多进程TCP服务器
目录 python day 20: 线程池与协程 2. 线程 3. 进程 4. 协程:gevent模块,又叫微线程 5. 扩展 6. 自定义线程池 7. 实现多进程TCP服务器 8. 实现多线程TCP ...
- Python 多线程和线程池
一,前言 进程:是程序,资源集合,进程控制块组成,是最小的资源单位 特点:就对Python而言,可以实现真正的并行效果 缺点:进程切换很容易消耗cpu资源,进程之间的通信相对线程来说比较麻烦 线程:是 ...
- 『Python』 ThreadPool 线程池模板
Python 的 简单多线程实现 用 dummy 模块 一句话就可以搞定,但需要对线程,队列做进一步的操作,最好自己写个线程池类来实现. Code: # coding:utf-8 # version: ...
- python爬虫之线程池和进程池
一.需求 最近准备爬取某电商网站的数据,先不考虑代理.分布式,先说效率问题(当然你要是请求的太快就会被封掉,亲测,400个请求过去,服务器直接拒绝连接,心碎),步入正题.一般情况下小白的我们第一个想到 ...
- python小demo-01: 线程池+多进程实现cpu密集型操作
起因: 公司有一个小项目,大概逻辑如下: 服务器A会不断向队列中push消息,消息主要内容是视频的地址,服务器B则需要不断从队列中pop消息,然后将该视频进行剪辑最终将剪辑后的视频保存到云服务器.个人 ...
- 【Python】多线程-线程池使用
1.学习目标 线程池使用 2.编程思路 2.1 代码原理 线程池是预先创建线程的一种技术.线程池在还没有任务到来之前,创建一定数量的线程,放入空闲队列中.这些线程都是处于睡眠状态,即均为启动,不消耗 ...
- Python之路——线程池
1 线程基础 1.1 线程状态 线程有5种状态,状态转换的过程如下图所示: 1.2 线程同步——锁 多线程的优势在于可以同时运行多个任务(至少感觉起来是这样,其实Python中是伪多线程).但是当线程 ...
- python爬虫14 | 就这么说吧,如果你不懂python多线程和线程池,那就去河边摸鱼!
你知道吗? 在我的心里 你是多么的重要 就像 恩 请允许我来一段 freestyle 你们准备好了妹油 你看 这个碗 它又大又圆 就像 这条面 它又长又宽 你们 在这里 看文章 觉得 很开心 就像 我 ...
- Python爬虫之线程池
详情点我跳转 关注公众号"轻松学编程"了解更多. 一.为什么要使用线程池? 对于任务数量不断增加的程序,每有一个任务就生成一个线程,最终会导致线程数量的失控,例如,整站爬虫,假设初 ...
随机推荐
- 【翻译】.NET 5 Preview8发布
[翻译].NET 5 Preview8发布 今天,.NET 5预览8发布了,对于.NET5.0的功能开发已经完成了,这必须要排除待处理的bug,预览8是最后一次预览版本.预计11月正式的.NET5.0 ...
- Redis入门--进阶详解
Redis NoSql入门和概述 入门概述 互联网时代背景下大机遇,为什么用nosql 1.单机MySQL的美好年代 在90年代,一个网站的访问量一般都不大,用单个数据库完全可以轻松应付,在那个时候, ...
- CSS 段落/换行/缩进
CSS 段落/换行/缩进 1.盒模型 box-sizing: content-box|border-box|inherit; content-box(默认) : 实际宽度/高度 = width/hei ...
- Git的详细使用
关于Git的详细使用,下面博主的博客写的非常的详细! 可以参考一下. https://blog.csdn.net/qq_19835247/article/details/104620042 人生需要准 ...
- JS - 对金额数字实现千分位格式化处理
添加千分位处理: function fmoney(s, n) { n = n > 0 && n < = 20 ? n : 2; s = parseFloat((s + &q ...
- 【Go语言入门系列】(七)如何使用Go的方法?
[Go语言入门系列]前面的文章: [Go语言入门系列](四)之map的使用 [Go语言入门系列](五)之指针和结构体的使用 [Go语言入门系列](六)之再探函数 本文介绍Go语言的方法的使用. 1. ...
- LWPR
Scriptable Render Pipeline https://docs.unity3d.com/Manual/ScriptableRenderPipeline.html Unity轻量 ...
- node.js的安装及其相关环境变量的配置
笔者最近一直重置电脑,本来想换台mac,想了想还是加下配置吧. 于是慢慢的一直会去安装node 接下来进入教程环节 一.NodeJS下载 1.下载NodeJS安装包下载地址:NodeJS下载 2.开始 ...
- hdu 4010 Lct动态链接树
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include & ...
- 关于List的remove()方法
最近遇到一个小问题,我将其简化为下列代码,List的remove()方法在下列颜色注重的代码执行的源码也是不同的~ List<Integer> list=new ArrayList< ...