python 协程池gevent.pool_进程池\线程池,协程,gevent

目录

1. 进程池与线程池

2. 协程

3. gevent

4. 单线程下实现并发的套接字通信

首先写一个基于多线程的套接字

服务端:

from socket import *

from threading import Thread

def comunicate(conn):

while True: # 通信循环

try:

data = conn.recv(1024)

if len(data) == 0: break

conn.send(data.upper())

except ConnectionResetError:

break

conn.close()

def server(ip, port, backlog=5):

server = socket(AF_INET, SOCK_STREAM)

server.bind((ip, port))

server.listen(backlog)

while True: # 链接循环

conn, client_addr = server.accept()

print(client_addr)

# 通信

t=Thread(target=comunicate,args=(conn,))

t.start()

if __name__ == '__main__':

s=Thread(target=server,args=('127.0.0.1',8081))

s.start()

每连接上一个客户端便会创造一个线程 , 那么如果有一万个客户端的话服务端会产生一万个线程 , 然后服务端就炸了 , 所以要想个办法限制连接个数 , 即限制

1. 进程池\线程池

开启一个进程池 , 会开启一定个数的进程 , 然后将任务提交给进程就可以了

1 介绍

concurrent.futures模块提供了高度封装的异步调用接口

ThreadPoolExecutor:线程池,提供异步调用

ProcessPoolExecutor: 进程池,提供异步调用

Both implement the same interface, which is defined by the abstract Executor class.

2 基本方法

submit(fn, *args, **kwargs)

异步提交任务

map(func, *iterables, timeout=None, chunksize=1)

取代for循环submit的操作

shutdown(wait=True)

相当于进程池的pool.close()+pool.join()操作

wait=True,等待池内所有任务执行完毕回收完资源后才继续

wait=False,立即返回,并不会等待池内的任务执行完毕

但不管wait参数为何值,整个程序都会等到所有任务执行完毕

submit和map必须在shutdown之前

result(timeout=None)

取得结果

add_done_callback(fn)

回调函数

导入模块

from concurrent.futures import ProcessPoolExecutor

创建一个进程池

p=ProcessPoolExecutor(4)#进程数为4

提交任务, 有两种方式

a.同步调用:同步调用:提交完一个任务之后,就在原地等待,等待任务完完整整地运行完毕拿到结果后,再执行下一行代码,会导致任务是串行执行的

res=p.submit(function,参数一...).result()

b. 异步调用:提交完一个任务之后,不在原地等待,而是直接执行下一行代码,会导致任务是并发执行的,,结果futrue对象会在任务运行完毕后自动传给回调函数

res=p.submit(function,参数一...)

回调函数(用于异步调用)

每提交一个任务 , 会产生一个对象 , 给这个任务绑定了一个函数 , 这个函数会在你提交的任务完成后自动触发 , 且会将这个对象当作参数传给这个函数

这个函数用于处理子进程运行完之后产生的结果

多进程下的回调函数

from concurrent.futures import ProcessPoolExecutor

import time,os

import requests

def get(url):

print('%s GET %s' %(os.getpid(),url))

time.sleep(3)#处理的太快看不出效果 , 模拟多处理3秒

response=requests.get(url)#爬取网站内容

if response.status_code == 200:

res=response.text

else:

res='下载失败'

return res#返回爬取数据

# 到这里任务运行完了之后自动调用parse函数 ,

# 回调函数 , 处理任务的结果用

def parse(future):

time.sleep(1)

res=future.result()#future对象下的result为任务的返回值

print('%s 解析结果为%s' %(os.getpid(),len(res)))

if __name__ == '__main__':

urls=[

'https://www.baidu.com',

'https://www.sina.com.cn',

'https://www.tmall.com',

'https://www.jd.com',

'https://www.python.org',

'https://www.openstack.org',

'https://www.baidu.com',

'https://www.baidu.com',

'https://www.baidu.com',

]

#开启进程数为9的进程池

p=ProcessPoolExecutor(9)

start=time.time()

for url in urls:

# 异步调用:提交完一个任务之后,不在原地等待,而是直接执行下一行代码,会导致任务是并发执行的,,结果futrue对象会在任务运行完毕后自动传给回调函数

future=p.submit(get,url)

#将parse设为回调函数

future.add_done_callback(parse) #parse会在任务运行完毕后自动触发,然后接收一个参数future对象

p.shutdown(wait=True)

print('主',time.time()-start)

print('主',os.getpid())

多线程与多进程相同,只需将p=ProcessPoolExecutor(9)改为p=ThreadPoolExecutor(9)就可以了

2. 单线程下实现并发-------协程

目标:

在单线程下实现并发,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。

并发(多个任务看起来是同时执行就是并发):切换+保存状态

协程:

协程是单线程实现并发

注意:协程是程序员意淫出来的东西,操作系统里只有进程和线程的概念(操作系统调度的是线程)

在单线程下实现多个任务间遇到IO就切换就可以降低单线程的IO时间,从而最大限度地提升单线程的效率

强调

python的线程属于内核级别的,即由操作系统控制调度(如单线程遇到io或执行时间过长就会被迫交出cpu执行权限,切换其他线程运行)

单线程内开启协程,一旦遇到io,就会从应用程序级别(而非操作系统)控制切换,以此来提升效率(!!!非io操作的切换与效率无关)

对比操作系统控制线程的切换,用户在单线程内控制协程的切换

优点如下

协程的切换开销更小,属于程序级别的切换,操作系统完全感知不到,因而更加轻量级

单线程内就可以实现并发的效果,最大限度地利用cpu

缺点如下

协程的本质是单线程下,无法利用多核,可以是一个程序开启多个进程,每个进程内开启多个线程,每个线程内开启协程

协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程

总结

必须在只有一个单线程里实现并发

修改共享数据不需加锁

用户程序里自己保存多个控制流的上下文栈

附加:一个协程遇到IO操作自动切换到其它协程(如何实现检测IO,yield、greenlet都无法实现,就用到了gevent模块(select机制))

3. gevent

他是一个第三方的库 , 可以实现在单线程内遇到 IO 任务自动切换

geven是不能直接识别的 需要在整个文件最前面加上一行代码

from gevent import monkey;monkey.patch_all()

步骤 :

打补丁

导入from gevent import spawn

定义有 IO 操作的任务(函数)

将多个任务分别提交给协程

g1=spawn(函数名,函数的参数)

g2=spawn(函数名,函数的参数)

等待两个协程运行完 ,

g1.join()

g2.join()

math?formula=%5Ccolor%7Bred%7D%7B%E6%B3%A8%E6%84%8F%7D:因为这里是异步调用 , 主线程代码运行完了 , 主线程就会死掉 , 协程里面的任务也不会运行完 就跟着死了, 所以要加上join方法 ,如果主线程要运行很久 , 或者是一个死循环 , 就不用加join方法 ,即上面的的第五步就可以忽略

from gevent import monkey;monkey.patch_all()

from gevent import spawn,joinall #pip3 install gevent

import time

def play(name):

print('%s play 1' %name)

time.sleep(5)

print('%s play 2' %name)

def eat(name):

print('%s eat 1' %name)

time.sleep(3)

print('%s eat 2' %name)

start=time.time()

g1=spawn(play,'王昭锦')

g2=spawn(eat,'王昭锦')

g1.join()

g2.join()

# joinall([g1,g2]) #上面两步可以并成这一步

print('主',time.time()-start)

运行结果如下:

'''

王昭锦 play 1

王昭锦 eat 1

王昭锦 eat 2

王昭锦 play 2

主 5.009259223937988

'''

4. 单线程下实现并发的套接字通信

服务端:

from gevent import monkey;monkey.patch_all()

from socket import *

from gevent import spawn

def comunicate(conn):

while True: # 通信循环

try:

data = conn.recv(1024)

if len(data) == 0: break

conn.send(data.upper())

except ConnectionResetError:

break

conn.close()

def server(ip, port, backlog=5):

server = socket(AF_INET, SOCK_STREAM)

server.bind((ip, port))

server.listen(backlog)

while True: # 链接循环

conn, client_addr = server.accept()

print(client_addr)

# 通信

spawn(comunicate,conn)

if __name__ == '__main__':

g1=spawn(server,'127.0.0.1',8080)

g1.join()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/440497.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java poi 3.13_Java 读取Excl文件 (poi-3.13)

最近做项目遇到了读取Excel数据到数据库做数据的初始化。于是找一个。发现(poi-3.13)可以解决问题。可以解析两种格式(xlsx和xls)以下是实现的步骤1.下载poi3.13包,地址(http://poi.apache.org/download.html#POI-3.13)2.学习APi。接下来是还是demo来说明问题吧&…

【CodeChef - CLIQUED 】Bear and Clique Distances(建图,缩点技巧,思维)

题干: 解题报告: 主要就是在于怎么处理那个前K个点:组成一个团。换句话说,缩成一个点。先直接当成每个点多了k条边来处理,T了。想想也是啊,要是K1e5,那就是1e10条边了。。刚开始尝试了半天缩点&…

【HDU - 5649】DZY Loves Sorting(线段树,区间更新区间查询,思维,01缩数变换,线段树分割)

题干: DZY has a sequence a[1..n]a[1..n]. It is a permutation of integers 1∼n1∼n. Now he wants to perform two types of operations: 0lr0lr: Sort a[l..r]a[l..r] in increasing order. 1lr1lr: Sort a[l..r]a[l..r] in decreasing order. After doin…

php错误403_phpstudy访问文件报错403/Forbidden解决办法

使用phpstudy访问WWW目录下的文件时,浏览器提示Forbidden错误,没有访问权限。我在网上搜索了喝多资料以及本人亲自尝试过后,总结了一下两种方法。方法一:打开phpStudy,点击按键“其他选项菜单”>找到phpStudy配置&g…

【CodeForces - 294B】Shaass and Bookshelf(枚举,贪心,思维,组内贪心组间dp)

题干: Shaass has n books. He wants to make a bookshelf for all his books. He wants the bookshelfs dimensions to be as small as possible. The thickness of the i-th book is ti and its pages width is equal to wi. The thickness of each book is eith…

mac php开发集成环境,MAC OS X下php集成开发环境mamp

之前苦于mac上搭建本地服务器之艰辛,找寻好久都没找到一款类似windows上集成的本地服务器环境,诸如phpstudy,xampp,appserv,虽说xampp也有mac版,但不知为何不是Apache启动不了,这里小编为大家分享了MAC OS X 下php集成…

php获取手机目录,php如何获取手机型号

手机App中判断平台,可以根据$_SERVER[HTTP_USER_AGENT]中的内容来判断浏览器类型或手机平台。(推荐学习:PHP编程从入门到精通)iPhone UA:Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, l…

【CodeForces - 920E】Connected Components? (dsu,补图连通块,STLset+map,bfs 或bitset)

题干: You are given an undirected graph consisting of n vertices and edges. Instead of giving you the edges that exist in the graph, we give you m unordered pairs (x, y) such that there is no edge between x and y, and if some pair of vertices…

【牛客 - 551F】CSL 的神奇序列(推公式,猜结论,母函数)

题干: 链接:https://ac.nowcoder.com/acm/contest/551/F 来源:牛客网 题目描述 CSL 有一个神奇的无穷实数序列,他的每一项满足如下关系: 对于任意的正整数 n ,有 , 并且 。 CSL 很清楚这样的序列是唯…

java什么时候创建进程,Java创建进程

Java创建进程1 进程的概念 11.1 进程的概念 11.2 进程的特征 11.3 进程与线程区别 12 进程的创建 12.1 JAVA进程的创建 12.1.1 ProcessBuilder 22.1.2 Runtime 32.1.3 Process 42.2 实例 52.2.1 创建子进程 52.2.2 进程阻塞问题 72.2.3 在java中执行java程序 111 进程的概念1.1…

【牛客 - 157E】青蛙(floyd最短路,建图)

题干: 链接:https://ac.nowcoder.com/acm/contest/157/E 来源:牛客网 题目描述 有一只可爱的老青蛙,在路的另一端发现了一个黑的东西,想过去一探究竟。于是便开始踏上了旅途 一直这个小路上有很多的隧道&#xff0…

php移动端url,什么是PC和移动端URL路径规范化

什么叫PC和手机端URL途径规范性在网址百度搜索引擎提升的全过程中,会牵涉到途径方位的难题。网址中的同一个网页页面只相匹配一个网站地址。一个规范化和简易的网站地址有利于检索和捕捉客户的记忆力,回绝好几条途径,偏向同一个网页页面&…

matlab的diray在哪,matlab笔记

matlab笔记 目录 P5第一章——matlab 概述与格式 P10eps 浮点相对精度inf 无穷大i 或 j 虚数单位pi 圆周率nan 非数nargin 函数输入变量数目nargout 函数输出变量数目realmax 最大正实数realmin 最小正实数real( ) 实部imag( ) 虚部abs( ) 绝对值angle( ) 复数的相位角**matlab…

【CodeForces - 190E】Counter Attack (补图bfs,卡常,dsu)

题干&#xff1a; 无向图中给定n个顶点&#xff0c;m条不存在的边(除了这m条边&#xff0c;其余都存在)&#xff0c;求图的连通分量&#xff0c;及每个连通分量的大小。 解题报告&#xff1a; https://codeforces.com/blog/entry/4556 AC代码&#xff1a; #include<cstd…

matlab 多径 时变 信道 冲击响应,无线信道—时变冲激响应

图1无线信道的作用可以分成大尺度效应和小尺度效应。大尺度的效应就是改变了信号的平均功率&#xff0c;即B点的功率是A点的1/L。因此可以将图1等效成图2图2其中C点的平均功率等于B点的平均功率。L的数值可根据传播模型确定。影响接收机性能的只是信噪比&#xff0c;因此&#…

matlab中均线交易策略,【每日一策】Matlab量化交易策略之 均线选股策略

策略名称&#xff1a;均线选股策略策略说明&#xff1a;对沪深300全市场扫描买入条件&#xff1a;1 短均线大于长均线2 最近N个交易日短均线大于长均线的次数满足某个阈值3 当前交易日的长均线值处于某个高位出场条件&#xff1a;止损&#xff1a;价格跌破入场价的一定百分比止…

docker php 乱码,如何解决docker安装zabbix5.0界面乱码

如何解决docker安装zabbix5.0界面乱码&#xff1f;zabbix图形界面乱码如下&#xff1a;解决&#xff1a;docker部署zabbix-web和源码安装zabbix-web一样&#xff0c;字体都是存储在/usr/share/zabbix/assets/fonts/1、从windown拷贝simkai.ttf(楷体)文件到docker的zabbix-web里…

【POJ - 1330】Nearest Common Ancestors(lca,模板题)

题干&#xff1a; A rooted tree is a well-known data structure in computer science and engineering. An example is shown below: In the figure, each node is labeled with an integer from {1, 2,...,16}. Node 8 is the root of the tree. Node x is an ancestor o…

java redis 流水线,Redis系列(1) —— 流水线

写在前面去年下半年&#xff0c;出于学习Redis的目的&#xff0c;在看完《Redis in Action》一书后&#xff0c;开始尝试翻译Redis官方文档。尽管Redis中文官方网站有了译本&#xff0c;但是看别人翻译好的和自己翻译英文原文毕竟还是有很大的不同。这一系列文章之前发布在GitB…

【HDU - 6187】Destroy Walls(思维,最大生成树)

题干&#xff1a; Long times ago, there are beautiful historic walls in the city. These walls divide the city into many parts of area. Since it was not convenient, the new king wants to destroy some of these walls, so he can arrive anywhere from his castl…