• 协程


    协程概念

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

    线程:执行单位,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()
  • 相关阅读:
    如何做一个按钮二个事件
    JavaScript中onmouseover时如何让鼠标指针变成一个小手状
    英语口语整理,灵活运用了,口语基本就没问题了
    javascript 传递 '' 时出错 换成 '&' ok
    一个按钮触发两个事件可以吗?
    Select中DISTINCT关键字的用法?
    使下拉框某项不可选的方法
    新打开窗口属性 a href
    调试和测试 Swing 代码
    打造专业外观九宫图
  • 原文地址:https://www.cnblogs.com/mcc61/p/10848899.html
Copyright © 2020-2023  润新知