一.进程池与线程池
# def task(name): # print("%s%s is running " %(name,os.getpid())) # time.sleep(random.randint(1,3)) # # if __name__ == '__main__': # p=ProcessPoolExecutor(4) #创建进程池的个数 # #提交任务 # #同步提交:提交完一个任务后,就在原地等待,等待任务完完整整地运行完毕后拿到结果,在执行下一行代码,会导致任务是串行执行的 # #异步提交:提交完一个任务后,不在原地等待,而是直接执行下一行代码,会导致执行是并发的 # li=[] # #同步提交 # for i in range(10): # # res = p.submit(task,'线程id:').result() # # print(res) # # #异步提交 # # future=p.submit(task,"线程id:") # li.append(future) # # p.shutdown(True) #关闭进程池的入口,并且在原地等待进程池内所有任务运行完毕 # # for future in li: # print(future.result()) # print("主")
二.
def get(url): print("%s GET %s" % (current_thread().name, url)) time.sleep(3) response = requests.get(url) if response.status_code == 200: res = response.text else: res = '下载失败' return res def pase(future): time.sleep(1) res= future.result() print("%s 解析的结果为:%s" % (current_thread().name, len(res))) if __name__ == '__main__': urls = ['http://www.baidu.com', 'http://www.sina.com', 'http://www.tmall.com', 'http://www.jd.com', 'http://www.python.org', 'http://www.openstack.com' ] p = ProcessPoolExecutor(6) li = [] strat = time.time() for url in urls: # 可以理解为开启进程数的个数 future = p.submit(get, url) future.add_done_callback(pase) #pase会将任务运行完毕后会自动触发,然后接受一个参数futur对象 p.shutdown(True) #关闭进程池的入口,并且在原地等待进程池内所有任务运行完毕 print("主", time.time() - strat)
三.利用线程池和进程池实现套接字的并发
from socket import * from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor from multiprocessing import Process 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(): server = socket(AF_INET, SOCK_STREAM) server.bind(("127.0.0.1", 8081)) server.listen(5) while True: # 链接循环 conn, client_addr = server.accept() print(client_addr) # 通信 t = Process(target=comunicate, args=(conn,)) t.start() if __name__ == '__main__': p = ProcessPoolExecutor(6) for i in range(4): future = p.submit(server, ) # future.add_done_callback(comunicate) # 回调函数 communciate会将任务运行完毕后会自动触发,然后接受一个参数futur对象
四.协程
''' 1. 目标: 在线程下实现并发 并发(多个任务看起来是同时执行就是并发):切换+保存状态 2. 协程: 协程是单线程实现并发 注意:协程是程序员意淫出来的东西,操作系统里只有进程和线程的概念(操作系统调度的是线程) 在单线程下实现多个任务间遇到IO就切换就可以降低单线程的IO时间,从而最大限度地提升单线程的效率 ''' #串行执行 import time def func1(): for i in range(10000000): i+1 def func2(): for i in range(10000000): i+1 start = time.time() func1() func2() stop = time.time() print(stop - start) #基于yield并发执行 import time def func1(): while True: print('func1') 10000000+1 yield def func2(): g=func1() for i in range(10000000): print('func2') time.sleep(100) i+1 next(g) start=time.time() func2() stop=time.time() print(stop-start)
五.
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)