zoukankan      html  css  js  c++  java
  • python全栈脱产第37天------进程池与线程池、协程、gevent模块、单线程下实现并发的套接字通信

    一、进程池与线程池

      调用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()
  • 相关阅读:
    JedisConnectionException: java.net.ConnectException: Connection refused
    Mysql索引整理总结
    jstat命令总结
    Java死锁排查和Java CPU 100% 排查的步骤整理
    Spring-Session实现Session共享实现原理以及源码解析
    Spring-Session实现Session共享Redis集群方式配置教程
    Spring-Session实现Session共享入门教程
    Redis高可用集群-哨兵模式(Redis-Sentinel)搭建配置教程【Windows环境】
    jsp获取当前日期,包括星期几
    使用joda-time工具类 计算时间相差多少 天,小时,分钟,秒
  • 原文地址:https://www.cnblogs.com/zhouyi0316/p/9622522.html
Copyright © 2011-2022 走看看