协程与线程套接字通讯
基于多线程实现套接字服务端支持并发,服务端
 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 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 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('主')
 补充:1
   p=ProcessPoolExecutor(9)
  start=time.time()
  for url in urls:
   future=p.submit(get,url)
   # 异步调用:提交完一个任务之后,不在原地等待,而是直接执行下一行代码,会导致任务是并发执行的,,结果futrue对象会在任务运行完毕后自动传给回调函数
   future.add_done_callback(parse)  #parse会在任务运行完毕后自动触发,然后接收一个参数future对象
   p.shutdown(wait=True)
 补充:2
   p=ThreadPoolExecutor(4)
  for url in urls:
   future=p.submit(get,url)
   future.add_done_callback(parse)
  p.shutdown(wait=True)
 协程
  1. 目标:
   在线程下实现并发
    并发(多个任务看起来是同时执行就是并发):切换+保存状态
  2. 协程:
   协程是单线程实现并发
   注意:协程是程序员意淫出来的东西,操作系统里只有进程和线程的概念(操作系统调度的是线程)
   在单线程下实现多个任务间遇到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,'刘清正')
 g2=spawn(eat,'刘清正')
 # g1.join()
 # g2.join()
 joinall([g1,g2])
 print('主',time.time()-start)

posted on 2018-09-10 20:07  吴之家  阅读(93)  评论(0编辑  收藏  举报