• 4 May 18 socketserver 并发编程复习


    4 May 18
    复习:
    1、 串行不是单纯的一个一个来,串行是按照规定好的顺序一个一个来
    2、 listen(5): 规定的是最大的请求数;池: 规定的是最多连接数
    3、 网络IO:收信息(wait + copy)和发消息(copy)
    4、 多路复用IO可调用模块:
    a、 select:本质是循环的问操作系统,随着元素的增加,效率降低
    b、 poll:可以放下比select多的对象。但本质还是循环的问操作系统,随着元素的增加,效率降低。
    c、 epoll:每个套接字都绑定一个回调函数,变被动为主动。Windows不支持epoll
    d、 selector(更高程度的封装)为当前计算机在以上三种模块中选择效率最高的
    5、 维持高并发的高效率模式:多进程+多线程+单线程下并发。例: BS架构中B/Nginx(sever)用的模式既以上模式
     
    socketserver:
    1、 多线程调: ThreadingTCPServer 或ThreadingUDPServer
    2、 多进程调: ForkingTCPServer 或 ForkingUDPServer (Windows系统无法调用)
    3、 ThreadingTCPServer: while循环+accept+启线程
    4、 ThreadingUDPServer: while循环+recvfrom+启线程
    5、 ThreadingTCPServer/ ThreadingUDPServer 传参时,bind&activate=True等价于bind + listen
    6、 对TCP部分,用socketserver产生的self.request 等价于用socket产生的conn
    7、 对UDP部分,用socketserver产生的self.request,为一个小元组,该元组的第一个元素为接收到的信息,第二个元素等价于用socket产生的server
    8、 源码查看:
    a、 主要的类分为三种类型(server(连接循环),request(通信循环),mixin(并发相关))
    b、 看源码从执行入口开始看
    c、 查看源码逻辑,可后续利用第三方源码封装自己的工具
    9、 基于tcp
    服务端:
    import socketserver
     
    # 通信循环
    class MytcpHandler(socketserver.BaseRequestHandler):
        def handle(self): #socketserver规定的,必须使用
            while True:
                try:
                    data = self.request.recv(1024)  # 1024 接收数据的最大限制
                    if not data: break  # 针对linux系统
                    self.request.send(data.upper())  # 注意:收发都是以bytes为单位
                except ConnectionResetError:
                    break
            self.request.close()
     
    if __name__ == '__main__':
        #连接循环
        server=socketserver.ThreadingTCPServer(('127.0.0.1',8080),MytcpHandler)
        server.serve_forever()
        print(server.server_address)
        print(server.RequestHandlerClass)
    print(server.socket) 
     
    客户端:
    import socket
     
    client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
     
    client.connect(('127.0.0.1',8080))
     
    while True:
        msg=input('>>: ').strip()
        client.send(msg.encode('utf-8'))
        data=client.recv(1024)
        print(data.decode('utf-8'))
     
    client.close()   
     
    10   基于UDP
    服务端:
    import socketserver
     
    # 通信循环
    class MyUDPHandler(socketserver.BaseRequestHandler):
        def handle(self):
            # print(self.request)
            res=self.request[0]
            print('客户端发来的数据:',res)
     
            self.request[1].sendto(res.upper(),self.client_address)
     
    if __name__ == '__main__':
        #连接循环
        server=socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyUDPHandler)
    server.serve_forever()
     
    客户端:
    import socket
    import os
     
    client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
     
    while True:
        msg='%s hello' %os.getpid()
        client.sendto(msg.encode('utf-8'),('127.0.0.1',8080))
     
        res,server_addr=client.recvfrom(1024)
    print(res)
     
    并发编程知识点总结
    一 网络编程
                           目标:编写一个C/S或B/S架构的基于网络通信的软件
     
                           1、C/S,B/S(*****)
                                                  server<===============>client
                                                  服务端特点:
                                                                         1、不间断地提供服务
                                                                         2、服务端要支持并发+高性能
     
                           2、互联网
                                                  互联网=物理连接介质+互联网协议(OSI七层***)
     
                                                  tcp三次握手,四次挥手 (*****)
                                                  tcp可靠,但不如udp效率高 (*****)
                                                  udp不可靠,但效率高 (*****)
     
                           3、socket(*****)
                                                  socket抽象层位于传输层与应用层之间
     
                           4、基于tcp协议的套接字通信(*****)
                                                  加上连接循环
                                                  加上通信循环
     
                           5、粘包问题:(*****)
                                                  tcp流式协议独有的粘包问题
                                                                         解决方法:自定义报头
     
                                                  udp数据报协议没有粘包问题
     
                           6、远程执行命令的小程序/上传下载文件的程序(*****)
     
                           7、基于udp协议的套接字通信(***)
     
    二 并发编程
                           目标:让服务端能够支持高并发+高性能
     
                           1、               操作系统发展史
                                                  多道技术(*****)
                                                                         产生背景:想要在单核下实现并发
                                                                         多道技术的核心:
                                                                                                1、空间上的复用(具体指的是内存中同时读入多道程序,多道程序的内存空间是物理隔离)
                                                                                                2、时间上的复用(复用cpu的时间)
                        切换+保存状态=》并发
     
                        切换:
                            1、遇到IO切换(可以提升效率)
                            2、运行时间过长或者有一个优先级更高的进程抢走了cpu(反而会降低效率)
     
                           2、进程
                                                  1、进程理论(*****)
                                                      1、进程与程序区别
                2、并发与并行
                并发:看起来同时运行,单核就可以实现并发,但是单核无法实现并行
                并行:真正意义上的同时运行,一个cpu同一时刻只能做一件事
                     只有多核才能同时做多件事,即并行的效果
                串行:按照固定的顺序一个个地执行
                                                      3、不同操作系统开启子进程的区别
                4、一个进程的三种运行状态
     
                                                  2、开启进程的两种方式(*****)
                了解:僵尸进程与孤儿进程(**)
     
                                                  3、守护进程(**)
     
                                                  4、互斥锁与信号量(**)
                                                      互斥锁就将并发变成一个一个的执行,牺牲了效率保证了数据安全
                                                      只有在多个任务修改共享的数据的时候才会考虑用互斥锁
     
                                                  5、IPC机制:队列,管道(*)
     
                                                  6、进程queue=管道+锁 (***)
     
                                                  7、生产者消费者模型(*****)
                                                      1、什么是生产者消费者模型?
                                                          模型指的是解决问题的一种套路
                                                          该模型中包含两种重要的角色:
                                                              生产者:生产数据的任务
                                                              消费者:处理数据的任务
     
                                                      2、什么用生产者消费者模型?
                                                          在程序中有明显地两类任务,一类负责生产数据,另外一个类则拿到生产的数据进行处理,此时就应该
                                                          考虑使用生产者消费者模型来处理这种问题
     
                                                      2、为什么要用生产者消费者模型?好处?
                                                          1、将生产者与消费者解开耦合
                                                          2、平衡了生产者的生产数据的能力和消费者处理数据的能力
                                                              原理:
                            解耦和指的是生产者不与消费者直接打交道,
                            生产者可以不停地往队里里放数据
                            消费者可以不停地从队列里取走数据进行处理
     
                                                      3、如何实现?
     
                           3、线程
                                                  1、线程理论(*****)
                                                      1、开一个进程内默认就有一个线程
                                                      2、线程vs进程
                                                          1、同一进程内的多个线程共享进程内的资源
                                                          2、创建线程的开销要远小于进程
     
                                                  2、开启线程的两种方式(*****)
                                                  3、守护线程(**)
                                                  4、互斥锁与信号量(**)
                                                  5、GIL vs 互斥锁(*****)
                                                      1、什么是GIL
                                                          GIL是全局解释器锁,是加到解释器身上的,
                                                          同一进程内的所有的线程,但凡执行,必须拿到解释器执行才能之心个,要拿到解释器必须先抢GIL
                                                          所以GIL可以被当做执行权限
     
                                                      2、GIL的影响
                                                          GIl会限制同一进程的内的多个线程同一时间只能有一个运行,也就说说python一个进程内的多线线程
                                                          无法实现并行的效果,即无法利用多核优势
     
                                                          然后多核提供的优势是同一时刻有多个cpu参与计算,意味着计算性能地提升,也就是说我们的任务是
                                                          计算密集型的情况下才需要考虑利用多核优势,此时应该开启python的多进程
     
                                                          在我们的任务是IO密集型的情况下,再多的cpu对性能的提升也用处不大,也就说多核优势在IO密集型程序面前
                                                          发挥的作用微乎其微,此时用python的多线程也是可以的
     
                                                      3、GIL vs 互斥锁
                                                          GIL保护的是解释器级别的数据
                                                          本质就是一个互斥锁,然后保护不同的数据就应该用不同的互斥锁,保护我们应用程序级别的数据必须自定义互斥锁
     
                                                          运行流程?
     
                                                  6、死锁现象与递归锁(**)
                                                  7、线程queue(***)
                                                  8、Event事件(**)
     
                           4、池(*****)
                                                  为何要用池:
                                                                         操作系统无法无限开启进程或线程
                                                                         池作用是将进程或线程控制操作系统可承受的范围内
                                                  什么时候用池:
                                                                         当并发的任务数要远超过操作系统所能承受的进程数或
                                                                         线程数的情况应该使用池对进程数或线程数加以限制
     
                                                  如何用池?
                                                                         池内装的东西有两种:
                                                                                                装进程:进程池
                                                                                                装线程:线程池
     
                                                                         进程线程池的使用
     
                                                  提交的两种方式:
                                                                         同步调用
                                                                         异步调用+回调机制
     
                                                                         tpool=tpool=ThreadPoolExecutor(3)
                                                                         tpool.submit(task,arg1,agr2....).add_done_callback(handle)
     
                                                  任务执行的三种状态:
                                                                         阻塞
                                                                                                阻塞
                                                                         非阻塞:
                                                                                                就绪
                                                                                                运行
     
                           5、单线程下实现并发(***)
                                                  协程:在应用程序级别实现多个任务之间切换+保存状态
     
                                                  高性能:
                                                                         单纯地切换,或者说么有遇到io操作也切换,反而会降低效率
                                                                         检测单线程下的IO行为,实现遇到IO立即切换到其他任务执行
     
                                                  gevent
     
                           6、网络IO模型(主要掌握理论***)
                                                  阻塞IO
                                                  非阻塞IO
                                                  IO多路复用
                                                  异步IO
  • 相关阅读:
    树莓派添加桌面快捷方式
    计算机网络
    django-auth2
    令牌桶算法-python
    linux centos-7 添加开机自启动脚本
    pymongodb-explain
    哈希表
    tcp/udp
    jemeter之jmeter+ant+jenkins搭建接口自动化测试环境
    jmeter之jmeter + ant + jenkins(二)Jenkins安装
  • 原文地址:https://www.cnblogs.com/zhangyaqian/p/py20180504.html
Copyright © 2020-2023  润新知