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爬虫之线程池
详情点我跳转 关注公众号"轻松学编程"了解更多. 一.为什么要使用线程池? 对于任务数量不断增加的程序,每有一个任务就生成一个线程,最终会导致线程数量的失控,例如,整站爬虫,假设初 ...
随机推荐
- SSM项目_Eclipse卡进程 一直loading加载spring-xx.xsd/无法加载SpringXSD文件
你遇到了套娃,请进https:////www.cnblogs.com/steamer/articles/12500645.html查看答案
- 专为seo新手准备的百度分享工具教程
http://www.wocaoseo.com/thread-178-1-1.html 百度分享工具是目前seo站长最为常用的工具之一,主要用来让用户分享来提高网站的流量,同时他也有很多实际有效的方式 ...
- File类 -《学堂在线》
File类的作用 ·创建.删除文件: ·重命名文件:判断文件的读写权限及是否存在: ·设置和查询文件的最近修改时间等: ·构造文件流可以使用File类的对象作为参数. //: FileTester.j ...
- Picker 组件的设计与实现
前言 今天的主题是 Picker 组件的设计与实现,Picker 组件是 NutUI 的一个拾取器组件,它用于显示一系列的值集合,用户可以滚动选择集合中一项,也可以支持多个系列的值集合供用户分别选择. ...
- 由浅入深理解 IOC 和 DI
目录 由浅入深理解 IOC 和 DI 开闭原则 OCP(Open Closed Principle) 面向抽象编程 逐步理解实现 IOC 和 DI 的过程(LOL Demo 示例) 比较尴尬的编写程序 ...
- centos 7 对用过yum更新的软件服务进行降级
centos 7 执行 yum update 会对现有服务软件进行更新,但是如果把不该升级的软件升级,彼此软件不兼容,如何进行降级,比如:kibana 必须与 elasticsearch 大版本相同, ...
- k8s部署mysql主从复制
Mysql主从 准备环境 一,准备软件 官方docker_image :Mysql5.7.28 Docker Version: 19.03.4 K8s api-version: ...
- 【免费】windows下如何生成tar.gz,一键生成tar.gz
废话 一.实验背景 tar.gz 是Linux和Unix下面比较常用的格式,一条命令就可以把文件压缩打包成tar.gz格式,然而这种格式在windows并不多见. Linxu服务器上,tar.gz 包 ...
- viewPager2的Bug
在使用数据绑定时,viewpager2的 android:layout_width 必需 match_parent,不然要么显示不正常,要么直接崩溃.
- 字符串对象跟xml格式的转换
package com.sunshen.jfids.testWebService.task; import java.io.File; import java.io.StringWriter; imp ...