zoukankan      html  css  js  c++  java
  • 协程

    协程概念

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

    线程:执行单位,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()
  • 相关阅读:
    what is NSParameterAssert?
    scrollView的几个属性contentSize contentOffset contentInset
    Explain awakeFromNib, initwithFrame usage
    strong、weak、unsafe_unretained(ARC);retain
    iOS 面试记(二)
    Python 编程规范 by @AKaras
    Python 的类的下划线命名
    Python中数值和进制转换
    Python基本运算符
    Ubuntu Linux系统下轻松架设nginx+php服务器应用
  • 原文地址:https://www.cnblogs.com/mcc61/p/10848899.html
Copyright © 2011-2022 走看看