线程queue、线程进程池、异步回调机制
1. 线程 queue
queue is especially useful in threaded programming when information must be exchanged safely between multiple threads.
queue 三种方法 :
class queue.Queue(maxsize=0) #队列:先进先出
import queue
q=queue.Queue()
q.put('first')
q.put('second')
q.put('third')
print(q.get())
print(q.get())
print(q.get())
'''
结果(先进先出):
first
second
third
'''
class queue.LifoQueue(maxsize=0) #堆栈:last in fisrt out
import queue
q=queue.LifoQueue()
q.put('first')
q.put('second')
q.put('third')
print(q.get())
print(q.get())
print(q.get())
'''
结果(后进先出):
third
second
first
'''
class queue.PriorityQueue(maxsize=0) #优先级队列:存储数据时可设置优先级的队列
import queue
q=queue.PriorityQueue()
#put进入一个元组,元组的第一个元素是优先级(通常是数字,也可以是非数字之间的比较),数字越小优先级越高
q.put((20,'a'))
q.put((10,'b'))
q.put((30,'c'))
print(q.get())
print(q.get())
print(q.get())
'''
结果(数字越小优先级越高,优先级高的优先出队):
(10, 'b')
(20, 'a')
(30, 'c')
'''
其他属性介绍
import queue # 线程queue
# q = queue.Queue(3.py) # 线程q对象,先进先出队列queue,容量为 3个
# 1.常规用法
# q.put(1)
# q.put(2)
# q.put(3.py)
# print(q.get())
# print(q.get())
# print(q.get())
# 2.不等待用法 以及 设置超时时间
# q.put(1)
# q.put(1)
# q.put(3.py)
# # q.put(4, block=False) # 等于q.put_nowait() # 非阻塞状态 # raise queue.Full
# q.put(4, timeout=3.py) # 设置超时时间
#
# print(q.get())
# print(q.get())
# print(q.get()) # q.get 与q.put 类似用法
2.进程池与线程池
在刚开始学多进程或多线程时,我们迫不及待地基于多进程或多线程实现并发的套接字通信,然而这种实现方式的致命缺陷是:服务的开启的进程数或线程数都会随着并发的客户端数目地增多而增多,这会对服务端主机带来巨大的压力,甚至于不堪重负而瘫痪,于是我们必须对服务端开启的进程数或线程数加以控制,让机器在一个自己可以承受的范围内运行,这就是进程池或线程池的用途,例如进程池,就是用来存放进程的池子,本质还是基于多进程,只不过是对开启进程的数目加上了限制。
前戏
官网:(https://docs.python.org/dev/library/concurrent.futures.html)
concurrent.futures模块提供了高度封装的异步调用接口
ThreadPoolExecutor:线程池,提供异步调用
ProcessPoolExecutor: 进程池,提供异步调用
Both implement the same interface, which is defined by the abstract Executor class.
基础属性
1、submit(fn, *args, **kwargs)
异步提交任务
2、map(func, *iterables, timeout=None, chunksize=1)
取代for循环submit的操作
3、shutdown(wait=True)
相当于进程池的pool.close()+pool.join()操作
wait=True,等待池内所有任务执行完毕回收完资源后才继续
wait=False,立即返回,并不会等待池内的任务执行完毕
但不管wait参数为何值,整个程序都会等到所有任务执行完毕
submit和map必须在shutdown之前
4、result(timeout=None)
取得结果
5、add_done_callback(fn)
回调函数
3.进程池 | 线程池
The ProcessPoolExecutor class is an Executor subclass that uses a pool of processes to execute calls asynchronously. ProcessPoolExecutor uses the multiprocessing module, which allows it to side-step the Global Interpreter Lock but also means that only picklable objects can be executed and returned.
class concurrent.futures.ProcessPoolExecutor(max_workers=None, mp_context=None)
An Executor subclass that executes calls asynchronously using a pool of at most max_workers processes. If max_workers is None or not given, it will default to the number of processors on the machine. If max_workers is lower or equal to 0, then a ValueError will be raised.
基础用法
# from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
# import os
# import time
# import random
#
#
# def task(name):
# """
#
# :param name:
# :return:
# """
# print("%s is running pid:%s" % (name, os.getpid()))
# time.sleep(random.randint(1, 8))
#
#
# if __name__ == '__main__':
# # pool = ProcessPoolExecutor(3) # 线程池与进程池属性方法基本相同
# pool = ThreadPoolExecutor(3)
# for i in range(10):
# pool.submit(task, "alex-%s" % i) # 异步调用
#
# print("main Process")
map的用法
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import os,time,random
def task(n):
print('%s is runing' %os.getpid())
time.sleep(random.randint(1,3))
return n**2
if __name__ == '__main__':
executor=ThreadPoolExecutor(max_workers=3)
# for i in range(11):
# future=executor.submit(task,i)
executor.map(task,range(1,12)) #map取代了for+submit
回调函数
可以为进程池或线程池内的每个进程或线程绑定一个函数,该函数在进程或线程的任务执行完毕后自动触发,并接收任务的返回值当作参数,该函数称为回调函数
# 1.同步调用 : 同步调用:提交完任务后,就在原地等待任务执行完毕,
# # 拿到结果,再执行下一行代码,导致程序是串行执行
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
import time
import random
def prepare(name):
"""
:param name:
:return:
"""
print("%s is prepare the dinner !" % name)
time.sleep(random.randint(3, 6))
dinner = chr(random.randint(65, 90))
return {"name": name, "dinner": dinner}
def eat(dinner_dict_obj):
"""
:param dinner_dict_obj:
:return:
"""
dinner_dict = dinner_dict_obj.result() # 返回一个对象 然后 result() 来返回结果
print("we having dinner %s is cooked by %s" % (dinner_dict["dinner"], dinner_dict["name"]))
if __name__ == '__main__':
pool = ThreadPoolExecutor(2)
# name_list = ["alex", "wxx", "tony", "jack"]
# for name in name_list:
# # 2、异步调用:提交完任务后,不地等待任务执行完毕,
# pool.submit(prepare, name).add_done_callback(eat) # 异步调用 拿到返回的执行结果future对象给一步函数
# 1.同步调用 : 同步调用:提交完任务后,就在原地等待任务执行完毕,
# 拿到结果,再执行下一行代码,导致程序是串行执行
# dinner_dict = pool.submit(prepare, "alex").result()
# eat(dinner_dict)
基于异步调用的简单网络爬虫
from concurrent.futures import ThreadPoolExecutor
import requests
import time
import re
def get(url):
print("download the %s" % url)
time.sleep(3)
resp = requests.get(url)
# print(resp.text)
return {"url": url, "content": resp.text}
def parse(resp_text_obj):
resp_text_dict = resp_text_obj.result()
par = re.compile(r"src=.*\.jpg|http://.*\.jpg") # 正则提取数据
print(re.findall(par, resp_text_dict["content"]))
print("%s is len %s" % (resp_text_dict["url"], len(resp_text_dict["content"])))
if __name__ == '__main__':
pool = ThreadPoolExecutor(3)
urls = [
"http://www.cnblogs.com/zjcode/p/8650090.html",
"http://www.521609.com/",
"http://dig.chouti.com/",
"http://www.bootcss.com/"
]
for url in urls:
pool.submit(get, url).add_done_callback(parse)
线程queue、线程进程池、异步回调机制的更多相关文章
- 定时器、线程queue、进程池和线程池
1.定时器 指定n秒后,执行任务 from threading import Timer,current_thread import os def hello(): print("%s he ...
- Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)
Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...
- Python 3 并发编程多进程之进程池与回调函数
Python 3 进程池与回调函数 一.进程池 在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间.多进程是实现并发的手段之一,需要注意 ...
- 单线程异步回调机制的缺陷与node的解决方案
一.node单线程异步的缺陷: 单线程异步的优点自然不必多说,node之所以能够如此快的兴起,其单线程异步回调机制相比于传统同步执行编程语言的优势便是原因之一.然而,开发一个node程序,其缺陷也是不 ...
- python语法基础-并发编程-进程-进程池以及回调函数
############### 进程池 ############## """ 进程池的概念 为什么会有进程池? 1,因为每次开启一个进程,都需要创建一个内存空间 ...
- 跨平台python异步回调机制实现和使用方法
跨平台python异步回调机制实现和使用方法 这篇文章主要介绍了python异步回调机制的实现方法,提供了使用方法代码 1 将下面代码拷贝到一个文件,命名为asyncore.py 代码如下: impo ...
- GIL,queue,进程池与线程池
GIL 1.什么是GIL(这是Cpython解释器) GIL本质就是一把互斥锁,既然是互斥锁,原理都是一样的,都是让多个并发线程同一时间只能有一个执行 即:有了GIL的存在,同一进程内的多个线程同一时 ...
- 线程queue与进程queue
进程queue: from multiprocessing import Queue,Process def func(qq): qq.put('function:我要放数据,给你来取...') if ...
- python并发编程之多进程2-------------数据共享及进程池和回调函数
一.数据共享 1.进程间的通信应该尽量避免共享数据的方式 2.进程间的数据是独立的,可以借助队列或管道实现通信,二者都是基于消息传递的. 虽然进程间数据独立,但可以用过Manager实现数据共享,事实 ...
随机推荐
- 类加载器:ClassLoader与Class的区别
1.类加载器 java字节码(类)的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验.解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类 ...
- Qt 使用#define+qDebug()输出调试信息
/******************************************************************************************* * Qt 使用 ...
- Mac设置SVN:Cornerstone3
前因 在windows下用Tortoisesvn.可惜Tortoisesvn没有Mac版,只能上知乎寻找适合于 Mac的SVN软件. 经过 找到了一款名为Cornerstone的软件.在App Sto ...
- MySQL 5.7笔记
1. 初始化 重命名my-default.ini为my.ini 添加character_set_server=utf8 运行mysqld --initialize 2. 重置密码 服务器运行: mys ...
- 模块(Modules)
一.引入模块 模块:当编写更大的应用程序时,所有的代码肯定会分成多个文件,这样便于维护,另外已经编写好的函数和对象在被多个程序中使用时,不用把函数和对象拷贝到每个程序中. 模块支持以上功能,在Pyth ...
- vc 编译器的一些精典报错
本篇将平时遇到的一些编译错误 , 记录于此 , 同时帖上分析
- 转载 vi替换windows换行符为linux换行符
1.用vi打开指定文本文件:vi filename.c 2.按 Esc 键,进入命令模式: 3.按 : 键 (按 Shift 键不放后,同时按 : 键)进入命令输入状态: 4.在冒号后输入:%s/^M ...
- HDU - 5628:Clarke and math (组合数&线性筛||迪利克雷卷积)
题意:略. 思路:网上是用卷积或者做的,不太会. 因为上一题莫比乌斯有个类似的部分,所以想到了每个素因子单独考虑. 我们用C(x^p)表示p次减少分布在K次减少里的方案数,由隔板法可知,C(x^p)= ...
- linux自学(八)之开始centos学习,安装tomcat
上一篇:linux自学(七)之开始ccentos学习,安装jdk 由于tomcat小,我们直接使用在线下载然后解压形式 首先,进入cd /usr/local目录下并创建tomcat目录,把tomcat ...
- python(六):面型对象--类的特殊方法
一.跟实例创建和执行有关的 __new__.__init__.__call__. 类加括号调用了__init__方法来创建一个实例对象.这一过程分成了两步: 类调用__new__来创建实例对象,__n ...