• 协程


    协程概念

    进程:资源单位,占用的是内存空间

    线程:执行单位,CPU直接执行的最小单位

    上面两个都是直接受到操作系统的控制,CPU在操作这些的时候,遇到io会切换,一个程序占用时间过长也会切换,那么为了实现将CPU的效率提升到最高,使用的方式就是并发,多个程序看起来像是一起进行的就是并发,并发的本质就是切换+保存状态

    协程:就是在单线程的情况下,让多个任务实现并发的效果(切换+保存状态)

    如何做到切换+保存状态呢?yield好像可以实现切换+保存状态

    import time
    def add():
        for i in range(100000):
            i+=1
            yield
    
    def com():
        a=add()
        for x in range(10):
            x+1
            time.sleep(2)#20.00367259979248
            next(a)
    start=time.time()
    com()
    
    print(time.time()-start
    import time
    def add():
        for i in range(100000):
            i+=1
            yield
    
    def com():
        a=add()
        for x in range(10):
            x+1
            # time.sleep(2)#20.00367259979248
            next(a)
    start=time.time()
    com()
    
    print(time.time()-start)  #19.555817365646362

    这个并不能实现检测io行为,有一个模块可以帮助我们实现检测io行为,就是gevent模块

    
    
    from gevent import monkey;monkey.patch_all()#监测所有io行为

    from gevent import spawn

    import time
    def play(name):
    print('%s is play iphone'%name)

    time.sleep(2)模拟网络延迟时间

    print('%s is playing '%name)

    def eat(name):
    print('%s is eating'%name)
    time.sleep(5)模拟网络延迟时间
    print('%s is eat'%name)
    start= time.time()

    # play('egon')
    # eat('egon')
    g1=spawn(play,'egon') 提交任务,提交完就不管了

    g2=spawn(eat,'egon')
    g1.join()所以要让上面的所有线程结束才可以
    g2.join()
    print(time.time()-start)直接打印的话就直接结束
     

    gevent实现了单线程下实现了自动监测io,基于这个我们可以尝试着做到利用这一个实现单线程下抗住并发进程的攻击,以socket通信为例

    #单线程下实现高并发,
    import socket
    
    from gevent import monkey;monkey.patch_all()
    from gevent import spawn
    
    
    def communicate(conn):#只用来通信
        while True:
            try:
    
                data = conn.recv(1024)
                if len(data) == 0: break
                print(data)
                conn.send(data.upper())
    
                pass
            except ConnectionResetError:
                break
        conn.close()
    
    def server(ip,port):#只用来建立连接
        server = socket.socket()
    
        server.bind((ip,port))
    
        server.listen(5)
        while True:
            conn,addr=server.accept()
    
            # print(addr)
            spawn(communicate,conn)
    
    if __name__ == '__main__':
        g1=spawn(server,'127.0.0.1',8090)
        g1.join()

    客户端

    import socket
    from threading import Thread,current_thread
    
    
    
    def clients():
        client = socket.socket()
        client.connect(('127.0.0.1', 8090))
        n=1
        while True:
            # info=input('>>:').strip().encode('utf-8')
            # if len(info)==0:continue
            data='%s %s'%(current_thread().name,n)
            n+=1
            client.send(data.encode('utf-8'))
            data=client.recv(1024)
            print(data)
    
    
    if __name__ == '__main__':
        # p_list=[]
        for i in range(10):
            p=Thread(target=clients)
            p.start()
            # p_list.append(p)
        # for p in p_list:
        #     p.join()
  • 相关阅读:
    oracle 按关键字排序前几行
    oracle 查看某表的前10行
    linux 7安装部署Redis
    oracle 查看库表状态
    centos 7 启动和关闭zabbix 服务
    oracle 创建用户密码及赋予登录权限
    linux 控制root登录宿主机时间
    centos 更改用户登录宿主机时间
    oracle 查询、创建、删除 数据库用户
    Django基础四之模板系统
  • 原文地址:https://www.cnblogs.com/mcc61/p/10848899.html
Copyright © 2020-2023  润新知