信号量

  其实本质上是锁,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. 数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解

    数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解 对数组有不了解的可以先看看我的另一篇文章,那篇文章对数组有很多详细的解析,而本篇文章则着重讲动态数组,另一篇文章链接 ...

  2. python3中异常处理方法 try-except-else-finally

    个人感觉逻辑上类似if else条件判断 但这是对语法错误以及抛出异常的处理 异常处理 try/except 异常捕捉可以使用 try/except 语句. 以下例子中,让用户输入一个合法的整数,但是 ...

  3. vue路由守卫+cookie实现页面跳转时验证用户是否登录----(二)设置路由守卫

    上一篇我们已经封装好了cookie方法,登录成功之后也可以吧用户信息存到cookie中,接下来需要在router/index.js中引入一下cookie.js文件 然后继续添加以下代码 /* * be ...

  4. 如何解读 Java IO、NIO 中的同步阻塞与同步非阻塞?

    原文链接:如何解读 Java IO.NIO 中的同步阻塞与同步非阻塞? 一.前言 最近刚读完一本书:<Netty.Zookeeper.Redis 并发实战>,个人觉得 Netty 部分是写 ...

  5. 答应我,用了这个jupyter插件,别再重复造轮子了

    1 简介 在使用Python.R等完成日常任务的过程中,可能会经常书写同样或模式相近的同一段代码,譬如每次使用matplotlib绘制图像的时候可以在开头添加下面两行代码来解决中文乱码等显示问题: p ...

  6. Oracle SQL 判断某表是否存在

    SQL> SELECT COUNT (*) as cnt FROM ALL_TABLES WHERE table_name = UPPER('your_table'); CNT -------- ...

  7. SpringMVC-结果跳转方式

    结果跳转方式 目录 结果跳转方式 1. ModelAndView 2. ServletAPI 3. SpringMVC实现 1. 无需视图解析器 2. 使用视图解析器 1. ModelAndView ...

  8. Python爬Boss,找工作,快人一步!!!

    通过职位搜索"Python开发",看下搜索的结果: https://www.zhipin.com/job_detail/?query=python开发&city=10102 ...

  9. JS基础回顾_函数

    函数 不要使用C风格的大括号 // log function return1() { return { name: 'oceans', } } function return2() { return ...

  10. UNIX编程艺术

    本文主要是 <UNIX编程艺术>的摘录,摘录的主要是我觉得对从事软件开发有用的一些原则. 对于程序员和开发人员来说,如果完成某项任务所需要付出的努力对他们是个挑战却又恰好还在力所能及的范围 ...