基于socket实现的线程并发
实现方式一:
实现socket模块的的服务器并发效果,类似于服务器一直处于监听状态,有数据过来我就不停的接收,通过socketserver模块就可以实现。(自行了解该模块)
实现方式二:
利用线程。
1 # 服务端 2 # 导入相关的模块 3 from threading import Thread 4 import socket 5 6 7 server = socket.socket() 8 server.blind(('127.0.0.1'. 8080)) 9 server.listen(5) 10 11 # 定义执行线程的函数 12 def task(conn): 13 while True: 14 try: 15 data = conn.recv(1024) 16 print(data.decode('utf-8')) 17 18 conn.send(data.upper()) 19 except ConnenctResetError: 20 break 21 conn.close() 22 23 24 25 while True: 26 conn,addr = server.accept() 27 print(addr) 28 t = Thread(target=task, args=(conn,)) 29 t.start()
1 # 客户端 2 import socket 3 4 cilent = socket.socket() 5 cilent.connect(('127.0.0.1', 8080)) 6 7 8 while True: 9 cmd = input('>>>>>>') 10 if len(cmd) == 0:continue 11 cilent.send(cmd.encode('utf-8')) 12 13 data = cilent.recv(1024) 14 print(data.decode('utf-8')) 15 cilent.close()
进程池和线程池
首先什么是池?
池,就是池塘。装载数据的容器。
进程池:相当于在池糖里固定的有若干个水坑,并且这个水坑就是在池塘创建好的时候规定好有若干个坑。
线程池:池子里有五个线程,来几个就是执行几个。
使用池的优点:
1.为了减缓计算机硬件的压力,避免计算机硬件设备崩溃
2.虽然减轻了计算机硬件的压力,但是一定程度上降低了持续的效率
使用进程池和线程池的目的:为了开设限定个数的进程和线程数,从而保证计算机的硬件安全。
1 # 实现进程池和线程池 2 # 进程池和线程池抖存在相同的模块下 concurrent.futures 3 from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor 4 5 import time 6 7 8 # 这里以开设线程为例,进程一样 9 # 开设一个池,最大数目为:5,默认最大为cpu的5倍 10 pool = ThreadPoolExecutor(5) 11 12 13 def task(n): 14 print(n) 15 time.sleep(3) 16 return n**2 17 18 19 # 接收回调函数的值,并处理的函数 20 def answer(obj): 21 print('answer is %s' %obj.result()) 22 23 24 if __name__ =="__main__": 25 # 创建10个线程 26 for i in range(10): 27 pool.submit(task,i).add_done_callback(answer) 28 29 # 等待线程结束调用 30 pool.stutdown() 31 print('主')
协程
协程的由来:为了实现单线程并发的效果。
协程:完全是我们高技术的人自己编出来的名词
通过代码层面自己监测io自己实现切换,让操作系统误认为你这个线程没有io
切换+保存状态就一定能够提升你程序的效率吗?不一定
当你的任务是计算密集型,反而会降低效率
如果你的任务是IO密集型,会提升效率
# 基于单线程实现的并发(socket)服务端 from gevent import monkey;monkey.patch_all() from gevent import spawn import socket def commuciate(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(commuciate, conn) if __name__ == '__main__': s1 = spawn(server) s1.join()
# 基于单线程实现的并发(socket)客户端 # 实现500个线程的协程 from threading import Thread import socket cilent = socket.socket() cilent.connect(('127.0.0.1', 8080)) def task(): while True: cilent.send(b'hello') data = cilent.recv(1024) print(data.decode('utf-8')) if __name__ == '__main__': for i in range(500): t = Thread(target=task) t.start()