1.进程池与线程池:
为什么要用“池”:池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务
池子内什么时候装进程:并发的任务属于计算密集型
池子内什么时候装线程:并发的任务属于IO密集型 1、进程池
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import time,os,random def task(x):
print('%s 接客' %os.getpid())
time.sleep(random.randint(2,5))
return x**2 if __name__ == '__main__':
p=ProcessPoolExecutor() # 默认开启的进程数是cpu的核数 # alex,武佩奇,杨里,吴晨芋,张三 for i in range(20):
p.submit(task,i) 2、线程池
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import time,os,random def task(x):
print('%s 接客' %x)
time.sleep(random.randint(2,5))
return x**2 if __name__ == '__main__':
p=ThreadPoolExecutor(4) # 默认开启的线程数是cpu的核数*5 # alex,武佩奇,杨里,吴晨芋,张三 for i in range(20):
p.submit(task,i)
2.同步、异步、阻塞、非阻塞
1、阻塞与非阻塞指的是程序的两种运行状态
阻塞:遇到IO就发生阻塞,程序一旦遇到阻塞操作就会停在原地,并且立刻释放CPU资源
非阻塞(就绪态或运行态):没有遇到IO操作,或者通过某种手段让程序即便是遇到IO操作也不会停在原地,执行其他操作,力求尽可能多的占有CPU 2、同步与异步指的是提交任务的两种方式:
同步调用:提交完任务后,就在原地等待,直到任务运行完毕后,拿到任务的返回值,才继续执行下一行代码
异步调用:提交完任务后,不在原地等待,直接执行下一行代码。等全部执行完毕后取出结果 from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import time,os,random def task(x):
print('%s 接客' %x)
time.sleep(random.randint(1,3))
return x**2 if __name__ == '__main__':
# 异步调用
p=ThreadPoolExecutor(4) # 默认开启的线程数是cpu的核数*5 # alex,武佩奇,杨里,吴晨芋,张三 obj_l=[]
for i in range(10):
obj=p.submit(task,i)
obj_l.append(obj) # p.close()
# p.join()
p.shutdown(wait=True) (等同于p.close()(不允许向池中放新任务) + p.join()) print(obj_l[3].result())
print('主') # 同步调用
p=ThreadPoolExecutor(4) # 默认开启的线程数是cpu的核数*5 # alex,武佩奇,杨里,吴晨芋,张三 for i in range(10):
res=p.submit(task,i).result() print('主')
2.协程
1、单线程下实现并发:协程 (为了提高效率;但不是说所有协程都会提升效率)
并发指的多个任务看起来是同时运行的;并发实现的本质:切换+保存状态
有效的协程在一定程度‘骗过’了CPU;通过自己内部协调,一遇到IO就切到自己的其他程序中,使得CPU以为这个程序一直在运行,从而使其更有可能处于就绪态或运行态,以更多的占用CPU。
2、实现并发的三种手段:
a)单线程下的并发;由程序自己控制,相对速度快
b)多线程下的并发;由操作系统控制,相对速度较慢
c)多进程下的并发;由操作系统控制,相对速度慢 3、基于yield保存状态,实现两个任务直接来回切换,即并发的效果 (但yield不会遇到阻塞自动切程序)
PS:如果每个任务中都加上打印,那么明显地看到两个任务的打印是你一次我一次,即并发执行的. import time
def consumer():
'''任务1:接收数据,处理数据'''
while True:
x=yield def producer():
'''任务2:生产数据'''
g=consumer()
next(g)
for i in range(10000000):
g.send(i) start=time.time()
producer() #1.0202116966247559
stop=time.time()
print(stop-start) # 纯计算的任务并发执行
import time
def task1():
res=1
for i in range(1000000):
res+=i
yield
time.sleep(10000) #yield不会自动跳过阻塞
print('task1') def task2():
g=task1()
res=1
for i in range(1000000):
res*=i
next(g)
print('task2') start=time.time()
task2()
stop=time.time()
print(stop-start) 一、单线程下实现遇到IO切换
1、用greenlet(封装yield,遇到IO不自动切)
from greenlet import greenlet
import time def eat(name):
print('%s eat 1' %name)
time.sleep(30)
g2.switch('alex') #只在第一次切换时传值
print('%s eat 2' %name)
g2.switch()
def play(name):
print('%s play 1' %name)
g1.switch()
print('%s play 2' %name) g1=greenlet(eat)
g2=greenlet(play)
g1.switch('egon') 2、用gevent模块(封装greenlet,不处理的话,遇到自己的IO才主动切)
import gevent def eat(name):
print('%s eat 1' %name)
gevent.sleep(5) #换成time.sleep(5),不会自动切
print('%s eat 2' %name)
def play(name):
print('%s play 1' %name)
gevent.sleep(3)
print('%s play 2' %name) g1=gevent.spawn(eat,'egon')
g2=gevent.spawn(play,'alex') # gevent.sleep(100)
# g1.join()
# g2.join()
gevent.joinall([g1,g2]) 3、用gevent模块(封装greenlet,处理的话,遇到其他IO也主动切)
from gevent import monkey;monkey.patch_all()
from threading import current_thread
import gevent
import time def eat():
print('%s eat 1' %current_thread().name)
time.sleep(5)
print('%s eat 2' %current_thread().name)
def play():
print('%s play 1' %current_thread().name)
time.sleep(3)
print('%s play 2' %current_thread().name) g1=gevent.spawn(eat)
g2=gevent.spawn(play) # gevent.sleep(100)
# g1.join()
# g2.join()
print(current_thread().name)
gevent.joinall([g1,g2])

Python(进程池与协程)的更多相关文章

  1. Python 线程池,进程池,协程,和其他

    本节内容 线程池 进程池 协程 try异常处理 IO多路复用 线程的继承调用 1.线程池 线程池帮助你来管理线程,不再需要每个任务都创建一个线程进行处理任务. 任务需要执行时,会从线程池申请线程,有则 ...

  2. Python、进程间通信、进程池、协程

    进程间通信 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 进程队列queue 不同于线程queue,进程 ...

  3. Python开发基础-Day32 进程间通信、进程池、协程

    进程间通信 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 进程队列queue 不同于线程queue,进程 ...

  4. python基础之进程间通信、进程池、协程

    进程间通信 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 进程队列queue 不同于线程queue,进程 ...

  5. python进程.线程和协程的总结

    I.进程: II.多线程threading总结 threading用于提供线程相关的操作,线程是应用系统中工作的最小单位(cpu调用的最小单位). Python当前版本的多线程没有实现优先级,线程组, ...

  6. 线程queue、线程进程池,协程

    线程queue import queue q = queue.Queue() #先进先出 q = queue.LifoQueue() #先进后出 t = queue.PriorityQueue() # ...

  7. python3下multiprocessing、threading和gevent性能对比----暨进程池、线程池和协程池性能对比

    python3下multiprocessing.threading和gevent性能对比----暨进程池.线程池和协程池性能对比   标签: python3 / 线程池 / multiprocessi ...

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

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

  9. 并发编程(六)——进程/线程池、协程、gevent第三方库

    进程/线程池.协程.gevent第三方库 一.进程/线程池 1.进程池 (1)什么是进程池 如果需要创建的子进程数量不大,可以直接利用multiprocess中的Process来创建.但是当需要创建上 ...

随机推荐

  1. 使用SQLite

    SQLite是一种嵌入式数据库,它的数据库就是一个文件.由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用程序中,甚至在iOS和Android的App中都可以集成. Python就 ...

  2. EM5-PE6B

    1. vocabulay 1.1 scary adj.令人恐怖的 This is a scary thing. you can construct some extremely scary scena ...

  3. SMP

    SMP(Symmetrical Multi-Processing):对称多处理技术,是指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统以及总线结构. 在smp系统中,所有的CP ...

  4. uvalive 3231 Fair Share 公平分配问题 二分+最大流 右边最多流量的结点流量尽量少。

    /** 题目: uvalive 3231 Fair Share 公平分配问题 链接:https://vjudge.net/problem/UVALive-3231 题意:有m个任务,n个处理器,每个任 ...

  5. Check the difficulty of problems - poj 2151 (概率+DP)

    有 T(1<T<=1000) 支队伍和 M(0<M<=30) 个题目,已知每支队伍 i 解决每道题目 j 的的概率 p[i][j],现在问:每支队伍至少解决一道题,且解题最多的 ...

  6. Educational Codeforces Round 22 E. Army Creation 主席树 或 分块

    http://codeforces.com/contest/813/problem/E 题目大意: 给出长度为n的数组和k,  大小是1e5级别. 要求在线询问区间[l, r]权值,  权值定义为对于 ...

  7. 开启GitHub模式,now!

    (原文地址为:http://www.karottc.com/blog/2014/06/15/current-doing/) 最近看到了一篇文章,该文章的作者将自己连续177天在github上commi ...

  8. Openstack(Kilo)安装系列之nova(七)

    控制节点 Before you install and configure the Compute service, you must create a database, service crede ...

  9. ubuntu 自动清理/tmp目录

    在Ubuntu系统中,在/tmp文件夹里面的内容,每次开机都会被清空,如果不想让他自动清理的话,只需要更改rcS文件中的TMPTIME的值. 我们看如何来修改 sudo vi /etc/default ...

  10. bootstrap基础学习十篇

    bootstrap字体图标(Glyphicons) a.什么是字体图标 字体图标是在 Web 项目中使用的图标字体.虽然,Glyphicons Halflings 需要商业许可,但是您可以通过基于项目 ...