zoukankan      html  css  js  c++  java
  • 协程

    进程:
    数据隔离
    数据不安全
    操作系统级别
    开销大
    能利用多核

    线程:
    数据共享
    数据不安全
    操作系统级别
    开销小
    不能利用多核
    对io操作的感知比较敏感(一些和文件操作相关的io只有操作系统能感知到)

    协程:
    数据共享
    数据安全
    操作系统不可见的
    用户级别的
    协程所有的切换都是基于用户的,只能根据用户级别能感知到的io操作
    做切换来规避(socket, 请求网页...)
    开销更小
    不能利用多核
    本质就是一条线程 多个任务在一条线程上来回切换,
    利用协程这个概念实现的内容:来规避io操作即尽可能将io操作降低到最低

    切换 并 规避io 的两个模块:
    gevent 利用了 greenlet 底层模块完成的切换 + 自动规避io的功能

    asyncio 利用了 yield 底层语法完成的切换 + 自动规避io的功能
    tornado 异步的web框架
    yield from - 其实是为了更好的实现协程
    send

    asyncio模块 基于python原生的协程的概念正式成立
    特殊的在python中提供协程功能的关键字:async await

    用户级别的协程有什么好处:
    减轻了操作系统的负担
    一条线程如果开了多条协程,那么给操作系统造成线程很忙的假象,这样能多争取一些时间片的时间
    来被cpu执行,这样提高了程序的效率

    2.gevent模块实现协程

    from gevent import monkey
    monkey.patch_all()
    import gevent
    import time
    
    
    def func():  # 带有io操作的内容写在函数里,然后将函数交给gevent
        print('start func')
        time.sleep(1)
        print('end func')
    
    
    g1 = gevent.spawn(func)
    g2 = gevent.spawn(func)
    g3 = gevent.spawn(func)
    
    # g1.join()  # 阻塞,直到协程g1任务执行结束
    # g2.join()
    # g3.join()
    gevent.joinall([g1, g2, g3])

    3.gevent实现socket并发的例子

    server端

    import socket
    print(socket.socket)   # path_all()前打印一次
    from gevent import monkey  # gevent如何检测是否能规避某个模块的io操作
    monkey.patch_all()
    import socket
    print(socket.socket)   # path_all()之后打印一次,不一样则有效
    import gevent
    
    
    def func(conn):
        while True:
            msg = conn.recv(1024).decode('utf-8')
            MSG = msg.upper()
    
            conn.send(MSG.encode('utf-8'))
    
    
    sk = socket.socket()
    sk.bind(('ip', port))
    sk.listen()
    
    while True:
        conn, _ = sk.accept()
    
        gevent.spawn(func, conn)

    client端

    import socket
    import time
    from threading import Thread
    
    
    def func(sk):
    
        while True:
            sk.send(b'hello')
    
            msg = sk.recv(1024)
            print(msg)
            time.sleep(0.5)
    
    
    sk = socket.socket()
    sk.connect(('10.19.50.157', 9001))
    
    for i in range(500):
        Thread(target=func, args=(sk, )).start()

    4.asyncio模块实现协程

    import asyncio
    
    
    async def func(name):
        print('start', name)
        # await + 可能会发生阻塞的方法
        # await 必须写在一个async函数里
        await asyncio.sleep(1)
        print('end')
    
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait([func('alex'), func('lgq')]))
  • 相关阅读:
    截取字符串
    已解决 4G内存条,显示只有2.99G
    UIWindows
    视图控制对象的生命周期与内存过低警告
    Using Autorelease Pools
    About Windows and Views
    惠普武汉实习生面试20110320
    什么时候使用活动图!求指导!
    我看微软把[Show Desktop]移动的原因
    喷子们说百度的手机操作系统
  • 原文地址:https://www.cnblogs.com/GOD-L/p/13781807.html
Copyright © 2011-2022 走看看