学习日记0910线程池与进程池 同步调用与异步调用 函数回调 协程
前提:线程池与进程池一般与同步调用与异步调用一起使用,而函数回调一般与异步调用一起使用
同步调用
提交完一个任务后,在原地等待,直到任务完完整整的运行完,得到返回的结果之后,再运行下一个函数,这样会导致任务之间是串行运行
进程池+同步调用
from concurrent.futures import ProcessPoolExecutor import time,os,random def task(name): print('%s:%s' % (name, os.getpid())) time.sleep((random.randint(1, 3))) return 123 if __name__ == '__main__': p = ProcessPoolExecutor(4) for i in range(10): res = p.submit(task,'同步调用').result() print(res) p.shutdown(wait=True) print('主函数')
进程池+异步调用+函数回调
from concurrent.futures import ProcessPoolExecutor import time import random, os def task(name): print('%s:%s' % (name, os.getpid())) time.sleep((random.randint(1, 3))) return 123 def re_task(future): time.sleep(1) print('函数task的运行结果是%s:%s' % (future.result(), os.getpid())) if __name__ == '__main__': p = ProcessPoolExecutor(4) for i in range(10): future = p.submit(task, 'pid') future.add_done_callback(re_task) # 函数回调的代码,实现的是将future对象传递给re_task函数,实现了函数之间的解耦合 p.shutdown(wait=True) print('zhu')
线程池+同步调用
from concurrent.futures import ThreadPoolExecutor from threading import current_thread import time,random def task(name): print('%s:%s' % (name, current_thread().name)) time.sleep((random.randint(1, 3))) return 123 if __name__ == '__main__': t = ThreadPoolExecutor(4) for i in range(10): res = t.submit(task,'pid').result() print(res) t.shutdown(wait=True) print('zhu')
线程池+异步调用+函数回调
from concurrent.futures import ThreadPoolExecutor from threading import current_thread import time,random def task(name): print('%s:%s' % (name, current_thread().name)) time.sleep((random.randint(1, 3))) return 123 def re_task(future): time.sleep(1) print('函数task的运行结果是%s:%s' % (future.result(), current_thread().name)) if __name__ == '__main__': t = ThreadPoolExecutor(4) for i in range(10): future = t.submit(task,'pid') future.add_done_callback(re_task) t.shutdown(wait=True) print('主线程!')
阻塞与非阻塞
阻塞:程序正在处理I\O操作程序会进入阻塞状态
非阻塞:程序正在处在运行状或者就绪态
程序的三种状态:
协程
只有在应用程序层次才有协程,在操作系统中没有协程这一说
协程的作用:
在单线程中实现并发
如果在程序的执行过程遇到了I\O的操作,就利用协程执行切换操作,这样可以大幅度的提高效率
利用协程实现套接字并发
服务端
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()
客户端
from threading import Thread,current_thread from socket import * def client(): client=socket(AF_INET,SOCK_STREAM) client.connect(('127.0.0.1',8080)) n=0 while True: msg='%s say hello %s' %(current_thread().name,n) n+=1 client.send(msg.encode('utf-8')) data=client.recv(1024) print(data.decode('utf-8')) if __name__ == '__main__': for i in range(500): t=Thread(target=client) t.start()