第三十七天

进程池、线程池 提交任务的两种方式:     同步调用:提交完一个任务之后,就在原地等待,等待任务完完整整地运行完毕拿到结果后,再执行下一行代码,会导致任务是串行执行的     异步调用:提交完一个任务之后,不在原地等待,结果???,而是直接执行下一行代码,会导致任务是并发执行的 异步调用:提交完一个任务之后,不在原地等待,而是直接执行下一行代码,会导致任务是并发执行的,,结果futrue对象会在任务运行完毕后自动传给回调函数 多线程实现套接字服务端支持并发 客户端.py from socket import *

client=socket(AF_INET,SOCK_STREAM) client.connect(('127.0.0.1',8081))

while True:     msg=input('>>: ').strip()     if len(msg) == 0:continue     client.send(msg.encode('utf-8'))     data=client.recv(1024)     print(data.decode('utf-8'))

服务端.py 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() 结果可以开启多个客户端,输入也有回复

from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor import time,random,os

def task(name,n):     print('%s%s is running' %(name,os.getpid()))     time.sleep(random.randint(1,3))     return n**2

if __name__ == '__main__':     # print(os.cpu_count())     p=ProcessPoolExecutor(4)     l=[]     for i in range(5):         # 同步提交         # res=p.submit(task,'进程pid: ',i).result()         # print(res)

        # 异步提交         future=p.submit(task,'进程pid: ',i)         l.append(future)

    p.shutdown(wait=True) #关闭进程池的入口,并且在原地等待进程池内所有任务运行完毕

    for future in l:         print(future.result())     print('主')

结果: 进程pid: 5888 is running 进程pid: 2744 is running 进程pid: 3516 is running 进程pid: 6320 is running 进程pid: 6320 is running 1 4 9 16 25 主

同步提交: 结果: 进程pid: 5080 is running 0 进程pid: 3060 is running 1 进程pid: 6636 is running 4 进程pid: 3372 is running 9 进程pid: 5080 is running 16 进程pid: 3060 is running 25 进程pid: 6636 is running 36 进程pid: 3372 is running 49 进程pid: 5080 is running 64 进程pid: 3060 is running 81 主

单线程下实现并发的套接字 客户端.py 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()

服务端.py 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()   协程 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) 结果: 4.8352766036987305

基于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(5)         i+1         next(g)

start=time.time() func2() stop=time.time() print(stop-start) 结果: func2 func1 func2 func1 后面无限循环

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)

结果: 一个进程五百个线程

猜你喜欢

转载自www.cnblogs.com/zhouhao123/p/9622305.html