1、socket 服务端实现高并发 网络编程服务端需要满足的要求:
①固定的IP和port
②24H提供服务
③能实现并发
# socket实现并发 # seerver import socket from threading import Thread server = socket.socket() server.bind((‘127.0.0.1‘,8080)) server.listen(5) def communicate(): # 通讯循环 while True: try: # 接收数据 data = conn.recv(1024) if len(data) == 0:break print(data) conn.send(data.upper()) except ConnectionResetError: break conn.close() #连接循环 while TRUE: conn addr = server.accept() # 开启线程 t = Thread(target = communicate,args=(conn,)) t.start()
# cliet import socket client = socket.socket() client.connect((‘127.0.0.1‘,8080)) # 通讯循环 while True: info = input(‘>>>‘).encode(‘utf-8‘) if len(info) == 0:continue client.send(info) data = client.recv(1024) print(data) conn.close() #连接循环 while TRUE: conn addr = server.accept() # 开启线程 t = Thread(target = communicate,args=(conn,)) t.start()
2、进程池和线程池
进程池和线程池都是为了减轻硬件负担,保证程序的运行,相对减少的运行速度
1 模块导入: from concurrent.futuers import ThreadPoolExecutor,ProcessPoolExecutor 2 实例化: #在不知道参数的情况下,默认为当前计算机的cpu个数*5 线程池:pool = ThreadpoolExecutor(N) 进程池:pool = ProcesspoolExecutor(N) 3 提交任务 pool.submit() 提交任务的两种方式: ① 同步:提交任务后,原地等待任务的返回结果,再执行下一步代码 ② 异步:提交任务后,不等待任务返回结果(通过回调函数拿到返回值),直接进下一步代码 4 回调函数:add_done_call() 异步提交后一旦任务有返回结果自定交给另外一个去执行 5 pool.shutdown: 关闭池子,并且等待池子中所有的任务运行完毕
例子
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor import time import os pool = ProcessPoolExecutor(5) # pool = ThreadPoolExecutor(5) def task(n): print(n,os.getpid()) time.sleep(2) return n**2 def call_back(n): print(‘拿到结果:%s‘%n.result()) if __name__ == ‘__main__‘: t_list = [] for i in range(20): # 回调函数,异步提交任务 future = pool.submit(task,i).add_done_callback(call_back) t_list.append(future) pool.shutdown() for p in t_list: print(">>>",p.result()) print(‘主‘)
3、协程
1、进程:资源单位
2、线程:执行单位
3、协程:单线程下实现并
4、协程是技术人员虚拟出来的的概念,对于操作系统并不存在
核心:切换+保存状态 作用就是将单线程的效率提升到最高,多进程下开多线程,多线程下用协程,实现高并发
优点:协程切换开销小,单线程内实现并发的效果,最大限度的利用cpu
缺点:无法利用多核,一旦阻塞整个线程就会阻塞
怎么使用
1 导入gevent模块 g1=gevent.spawn(func,1,,2,3,x=4,y=5)创建一个协程对象g1,spawn括号内第一个参数是函数名,如eat,后面可以有多个参数,可以是位置实参或关键字实参,都是传给函数eat的 2 g1.join() #等待g1结束 3 g1.value#拿到func1的返回值
协程实现高并发:
from gevent import monkey;monkey.patch_all() import socket from gevent import spawn def communicate(conn): while True: try: data = conn.recv(1024) if len(data)==0:break print(data.decode(‘utf-8‘)) conn.send(data.upper()) except ConnectionResetError: break conn.close() def server(): server = socket.socket() server.bind((‘127.0.0.1‘,8080)) server.listen(5) while True: conn,addr = server.accept() spawn(communicate,conn) if __name__ == ‘__main__‘: s1 = spawn(server) s1.join()
import socket from threading import Thread,current_thread def client(): client = socket.socket() client.connect((‘127.0.0.1‘,8080)) n = 1 while True: data = ‘%s %s‘%(current_thread().name,n) n+=1 client.send(data.encode(‘utf-8‘)) info = client.recv(1024) print(info) if __name__ == ‘__main__‘: for i in range(500): t = Thread(target=client) t.start() while True: conn,addr = server.accept() spawn(communicate,conn) if __name__ == ‘__main__‘: s1 = spawn(server) s1.join()
4 IO 模型
① 阻塞IO
② 非阻塞IO:非阻塞IO(服务端通信针对accept用s.setblocking(False)加异常捕获,cpu占用率过高)
③ IO多路复用:
在只检测一个套接字的情况下,他的效率连阻塞IO都比不上。因为select这个中间人增加了环节。
但是在检测多个套接字的情况下,就能省去wait for data过程
④ 异步IO
原文:https://www.cnblogs.com/king-home/p/10839601.html