1. 程式人生 > >python全棧脫產第37天------進程池與線程池、協程、gevent模塊、單線程下實現並發的套接字通信

python全棧脫產第37天------進程池與線程池、協程、gevent模塊、單線程下實現並發的套接字通信

rt thread adp targe rec 並發 urn pat return nco

一、進程池與線程池

  調用concurrent.futures下的ThreadPoolExecutor,ProcessPoolExecutor來實現

  提交任務有兩種方式:同步調用:提交完一個任務之後,就在原地等待,等待任務完完整整地運行完畢拿到結果後,在執行下一段代碼,是串行的

            異步調用:提交完一個任務之後,不在原地等待,直接運行下一段代碼,任務是並發的

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(10):
  # 同步提交
  # 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(‘主‘)
二、協程
  目標:在線程下實現並發:切換+保存狀態
  定義:協程就是單線程實現並發
  註意:協程是程序員意淫出來的東西,操作系統中只有進程和線程的概念(操作系統調度的是線程)
  用途:在單線程下實現多個任務間遇到IO操作切換就可以降低單線程的IO時間,從而最大限度地提升單線程的效率
三、gevent模塊
  
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,‘XXX‘)
g2=spawn(eat,‘XXX‘)

# g1.join()
# g2.join()
joinall([g1,g2])
print(‘主‘,time.time()-start)
四、單線程下實現並發的套接字通信
  服務端
  
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()

python全棧脫產第37天------進程池與線程池、協程、gevent模塊、單線程下實現並發的套接字通信