人工智能(PythonNet)—— 协程

一、协程

        定义:纤程,微线程。本质上只是一个线程在运行。

        功能特点:通过应用层程序,记录上下文栈区,实现在程序执行过程中的跳跃执行。由此可以选择不阻塞的部分执行以提升运行效率。

        优点:
                资源消耗少
                无需多线程那样进行多核之间的切换
                无需同步互斥操作
                IO并发性好

        缺点:
                无法利用计算机的多核资源

        python实现协程的基本手段:yield

        第三方工具:
                greenlet   gevent   evenless  stackless

        sudo  pip3 install greenlet
        sudo  pip3 install gevent

实际项目通常采用:多进程+协程的方式,实现多核高并发。

二、协程模块

1、greenlet

        gr = greenlet.greenlet()
        gr.switch()

2、gevent

        * 将协程事件封装为函数
        * 通过gevent将函数生成对应的协程对象
        * 通过协程对象完成协程功能的实现

        gevent.spawn(func,argv)
                功能:将事件变为协程事件并启动
                参数:func 出入一个函数变为协程
                            argv  给func位置传参
                返回值:协程对象

        gevent.joinall([g1,g2,g3.....])
                功能:阻塞回收协程
                参数:列表 要回收的协程对象

        gevent.sleep(n)
        功能:可以模拟IO阻塞的情况

from gevent import monkey
monkey.patch_all()
        功能 :修改socket的阻塞行为
        * 必须在导入socket之前调用

三、示例

1、greenlet

from greenlet import greenlet 

#协程事件
def test1():
    print(12)
    gr2.switch()
    print(34)
    gr2.switch()

def test2():
    print(56)
    gr1.switch()
    print(78)

#协程对象
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()  #启动gr1代表的协程

2、gevent

import gevent 

def foo(a,b):
    print("Running in foo",a)
    gevent.sleep(2)
    print("switch to foo again")

def bar():
    print("Running in bar")
    gevent.sleep(3)
    print("switch to bar again")

#将两个函数变为协程
f = gevent.spawn(foo,1,2)
b = gevent.spawn(bar)

#回收
gevent.joinall([f,b])

3、gevent_monkey

import gevent 
from gevent import monkey
#在导入socket前执行,改变socket的阻塞形态
monkey.patch_all()
from socket import *
from time import ctime

def server(port):
    s = socket()
    s.bind(('0.0.0.0',port))
    s.listen(5)
    while True:
        c,addr = s.accept()
        print('Connect from',addr)
        gevent.spawn(handler,c)

#处理客户端事件
def handler(c):
    while True:
        data = c.recv(1024).decode()
        if not data:
            break
        print('recv:',data)
        c.send(ctime().encode())
    c.clse()

if __name__ == "__main__":
    server(8080)

四、附录:目录

        人工智能(PythonNet)—— 目录汇总

猜你喜欢

转载自blog.csdn.net/qq_27297393/article/details/81325131
今日推荐