精华内容
下载资源
问答
  • Unity协程函数

    2017-07-21 14:12:49
    启动协程函数和停止协程函数参数类型要相同,比如使用协程函数的名字启动协程时,也要使用协程函数的名字停止协程。(Note: Do not mix the two arguments. If a string is used as the argument in StartCoroutine,...

    启动协程函数和停止协程函数参数类型要相同,比如使用协程函数的名字启动协程时,也要使用协程函数的名字停止协程。(Note: Do not mix the two arguments. If a string is used as the argument in StartCoroutine, use the string in StopCoroutine. Similarly, use the IEnumerator in both StartCoroutine and StopCoroutine.)

    代码块

    public class Ie : MonoBehaviour 
    {
        private IEnumerator ie;
        private Coroutine coroutine;
        void Start () 
        {
            ie = MyIE("1");
            StartCoroutine(ie);//方式一
    
            coroutine= StartCoroutine(MyIE("2"));//方式二
        }
        void Update () 
        {
            if (Input.GetKeyDown(KeyCode.Space))
            {
                StopCoroutine(ie);//方式一
                StopCoroutine(coroutine);//方式二
                //StopCoroutine(MyIE());//错误方式
            }
        }
        IEnumerator MyIE(string str)
        {
            while (true)
            {
                yield return null;
                Debug.Log(str);
            }
        }
    }
    展开全文
  • 协程函数

    2017-05-10 19:32:00
    协程函数是通过yield实现,通过单线程就可以实现并发的效果 直接上代码 import time """ 传统的生产者-消费者模型是一个线程写消息,一个线程取消息,通过锁机制控制队列和等待,但一不小心就可能死锁。 ...

    协程函数是通过yield实现,通过单线程就可以实现并发的效果

    直接上代码

    import time
    
    """
    传统的生产者-消费者模型是一个线程写消息,一个线程取消息,通过锁机制控制队列和等待,但一不小心就可能死锁。
    如果改用协程,生产者生产消息后,直接通过yield跳转到消费者开始执行,待消费者执行完毕后,切换回生产者继续生产,效率极高。
    """
    # 注意到consumer函数是一个generator(生成器):
    # 任何包含yield关键字的函数都会自动成为生成器(generator)对象
    
    def consumer():
        r = ''
        while True:
            # 3、consumer通过yield拿到消息,处理,又通过yield把结果传回;
            #    yield指令具有return关键字的作用。然后函数的堆栈会自动冻结(freeze)在这一行。
            #    当函数调用者的下一次利用next()或generator.send()或for-in来再次调用该函数时,
            #    就会从yield代码的下一行开始,继续执行,再返回下一次迭代结果。通过这种方式,迭代器可以实现无限序列和惰性求值。
            n = yield r
            if not n:
                return
            print('[CONSUMER] ←← Consuming %s...' % n)
            time.sleep(1)
            r = '200 OK'
    def produce(c):
        # 1、首先调用c.next()启动生成器
        next(c)
        n = 0
        while n < 5:
            n = n + 1
            print('[PRODUCER] →→ Producing %s...' % n)
            # 2、然后,一旦生产了东西,通过c.send(n)切换到consumer执行;
            cr = c.send(n)
            # 4、produce拿到consumer处理的结果,继续生产下一条消息;
            print('[PRODUCER] Consumer return: %s' % cr)
        # 5、produce决定不生产了,通过c.close()关闭consumer,整个过程结束。
        c.close()
    if __name__=='__main__':
        # 6、整个流程无锁,由一个线程执行,produce和consumer协作完成任务,所以称为“协程”,而非线程的抢占式多任务。
        c = consumer()
        produce(c)
        
        
    '''
    result:
    
    [PRODUCER] →→ Producing 1...
    [CONSUMER] ←← Consuming 1...
    [PRODUCER] Consumer return: 200 OK
    [PRODUCER] →→ Producing 2...
    [CONSUMER] ←← Consuming 2...
    [PRODUCER] Consumer return: 200 OK
    [PRODUCER] →→ Producing 3...
    [CONSUMER] ←← Consuming 3...
    [PRODUCER] Consumer return: 200 OK
    [PRODUCER] →→ Producing 4...
    [CONSUMER] ←← Consuming 4...
    [PRODUCER] Consumer return: 200 OK
    [PRODUCER] →→ Producing 5...
    [CONSUMER] ←← Consuming 5...
    [PRODUCER] Consumer return: 200 OK
    '''

    虽然它实现了并发,但并没有真正的提高效率,即没有区分是否使用io操作,如果能区分进行io操作则可以释放让别的函数执行计算代码,就提高了效率。

    使用 greenlet模块监控io操作:

    greenlet机制的主要思想是,生成器函数或者协程函数中的yield语句挂起函数的执行,直到稍后使用next()或send()操作进行恢复为止。可以使用一个调度器循环在一组生成器函数之间协作多个任务。greentlet是python中实现我们所谓的"Coroutine(协程)"的一个基础库.

    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()

    gevent模块实现协程:

    gevent是第三方库,通过greenlet实现协程,其基本思想是,当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。

    由于切换是在IO操作时自动完成,所以gevent需要修改Python自带的一些标准库,这一过程在启动时通过monkey patch完成:

    import gevent
    import time
    
    def foo():
        print("running in foo")
        gevent.sleep(2)
        print("switch to foo again")
    
    def bar():
        print("switch to bar")
        gevent.sleep(5)
        print("switch to bar again")
    
    start=time.time()
    
    gevent.joinall(
        [gevent.spawn(foo),
        gevent.spawn(bar)]
    )
    
    print(time.time()-start)

    当然,实际代码里,我们不会用gevent.sleep()去切换协程,而是在执行到IO操作时,gevent自动切换,代码如下:

    from gevent import monkey
    monkey.patch_all()
    import gevent
    from urllib import request
    import time
    
    def f(url):
        print('GET: %s' % url)
        resp = request.urlopen(url)
        data = resp.read()
        print('%d bytes received from %s.' % (len(data), url))
    
    start=time.time()
    
    gevent.joinall([
            gevent.spawn(f, 'https://itk.org/'),
            gevent.spawn(f, 'https://www.github.com/'),
            gevent.spawn(f, 'https://zhihu.com/'),
    ])
    
    # f('https://itk.org/')
    # f('https://www.github.com/')
    # f('https://zhihu.com/')
    
    print(time.time()-start)

    扩展:

    gevent是一个基于协程(coroutine)的Python网络函数库,通过使用greenlet提供了一个在libev事件循环顶部的高级别并发API。

    主要特性有以下几点:

    <1> 基于libev的快速事件循环,Linux上面的是epoll机制

    <2> 基于greenlet的轻量级执行单元

    <3> API复用了Python标准库里的内容

    <4> 支持SSL的协作式sockets

    <5> 可通过线程池或c-ares实现DNS查询

    <6> 通过monkey patching功能来使得第三方模块变成协作式

    gevent.spawn()方法spawn一些jobs,然后通过gevent.joinall将jobs加入到微线程执行队列中等待其完成,设置超时为2秒。执行后的结果通过检查gevent.Greenlet.value值来收集。

    1、关于Linux的epoll机制:
    
    epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的
    增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。epoll的优点:
    
    (1)支持一个进程打开大数目的socket描述符。select的一个进程所打开的FD由FD_SETSIZE的设置来限定,而epoll没有这个限制,它所支持的FD上限是
    最大可打开文件的数目,远大于2048。
    
    (2)IO效率不随FD数目增加而线性下降:由于epoll只会对“活跃”的socket进行操作,于是,只有”活跃”的socket才会主动去调用 callback函数,其他
    idle状态的socket则不会。
    
    (3)使用mmap加速内核与用户空间的消息传递。epoll是通过内核于用户空间mmap同一块内存实现的。
    
    (4)内核微调。
    
    2、libev机制
    
    提供了指定文件描述符事件发生时调用回调函数的机制。libev是一个事件循环器:向libev注册感兴趣的事件,比如socket可读事件,libev会对所注册的事件
    的源进行管理,并在事件发生时触发相应的程序。
    
    ps
    补充

     

    转载于:https://www.cnblogs.com/drchen/p/6837704.html

    展开全文
  • Coroutine协程函数 本质上是一个返回类型IEnumerator声明的函数,并且yield return语句包含在函数的某个地方。yield return语句,会执行暂停,并在下一帧从暂停处开始继续执行。 对复杂逻辑进行分帧,可以在主线程...

    Coroutine协程函数

    本质上是一个返回类型IEnumerator声明的函数,并且yield return语句包含在函数的某个地方。yield return语句,会执行暂停,并在下一帧从暂停处开始继续执行。

    对复杂逻辑进行分帧,可以在主线程内非堵塞的运行一个持续性的逻辑。

     

    实现原理:

    C#编译器会帮我们创建一个协程的类,而在开启一个协程时就会创建对应的对象,这个对象用来维护多次调用时协程的状态。正是要维护这些状态,所以协程内的本地变量也需要放到堆上,启动一个Coroutine所引起的内存消耗等同于一个类的固定成本加上这个 Coroutine所用到的局部变量总内存。而协程的生命周期就是跟着MonoBehaviour来走的。

     

    常用几种Coroutine操作:

    //会在下一帧开始的时候继续执行
    yield return null;
    
    //会在下一帧结束的时候继续执行
    yield return new WaitForEndOfFrame();
    yield return new WaitForFixedUpdate();
    yield return new WaitForSeconds(2.0f);
    
    //等待WWW返回
    WWW www = new WWW("http://www.baidu.com");
    yield return www;
    
    //等待另一个协程,这是把协程串联起来的关键
    yield return StartCoroutine(WaitAndPrint(0.5f));

     

    执行效率

    一个什么都不做的协程,至少需要两帧。

    某些条件下,可以写一套非协程代码,一套协程代码,如果数据在缓存中存在,直接执行非协程代码,否则执行协程代码,访问网络。减少无用的多帧操作。

     

    实际应用

    1、实现定时器

    2、利用协程,将复杂操作分帧计算,在协程内部统计一个数,当这个数大于一个值,清0并且yield return null,在下一帧开始的时候继续执行,不会堵塞主线程。

    3、通过下面这段逻辑,在协程中实现控制互斥区域

    //这里要引起注意的是,第一次写成if(m_DownLoading),

    //因为同时执行协程,m_DownLoading还没有被设置为true就达不到这样的效果了

    while (m_DownLoading)
    {
        yield return null;
    }
    m_DownLoading = true;

    4.等待另一个协程,把协程串联起来

    IEnumerator Work()
    {
        yield return StartCoroutine(NavToPos(start.localPosition));
        yield return StartCoroutine(Jump());
        yield return StartCoroutine(NavToPos(end.localPosition));
    }

     

    常见使用误区

     

    • 协程是在主线程
    • 必须依赖于一个启动它的mono,当协程程序所在脚本的active属性设置为false时,协程不会停止。
    • 当协程程序所在的gameobject的active属性设置为false时,协程停止。再次设置active属性为true,协程不会再启动。
    • 当协同程序所在脚本或gameobject被destroy时,协程会被终止。
    • 使用MonoBehaviour.StopCoroutine和MonoBehaviour.StopAllCoroutines来停止Coroutine。

     

    展开全文
  • 这篇文章主要介绍了Python 异步协程函数原理及实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下一、 asyncio1.python3.4开始引入标准库之中,内置对异步...

    这篇文章主要介绍了Python 异步协程函数原理及实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    一、 asyncio

    1.python3.4开始引入标准库之中,内置对异步io的支持

    2.asyncio本身是一个消息循环

    3.步骤:

    (1)创建消息循环

    (2)把协程导入

    (3)关闭

    4.举例:

    import threading

    # 引入异步io包

    import asyncio

    # 使用协程

    @ asyncio.coroutine

    def hello():

    print("Hello World!(%s)" % threading.current_thread())

    print("Start......(%s)" % threading.current_thread())

    yield from asyncio.sleep(5)

    print("Done.....(%s)" % threading.current_thread())

    print("Hello again!(%s)" % threading.current_thread())

    # 启动消息循环

    loop = asyncio.get_event_loop()

    # 定义任务

    tasks = [hello(), hello()]

    # asyncio使用wait等待task执行完毕

    loop.run_until_complete(asyncio.wait(

    tasks))

    # 关闭消息循环

    loop.close()

    2019111383546381.jpg?2019101383617

    二、asyncio and await

    1.为了更好的表示异步io

    2.python3.5引入

    3.让协程代码更加简洁

    4.使用上,可以简单的进行替换

    (1)用async来替换@asyncio,coroutine

    (2)用await来替换yield from

    按照上面这个语法可以来改写前面的例子,运行结果是完全一致的

    三、aiohttp

    1.asyncio实现单线程的并发io,在客户端用处不大

    2.在服务端可以asyncio+coroutine配合,因为http是io操作

    3.asyncio实现了tcp,udp,ssl等协议

    4.aiohttp是基于asyncio实现的http框架

    5.例子:

    import asyncio

    from aiohttp

    import web

    async def index(request):

    await asyncio.sleep(0.5)

    return web.Response(body = b "

    Index

    ")

    async def hello(request):

    await asyncio.sleep(0.5)

    text = "

    hello,%s!

    " % request.match_info[

    "name"]

    return web.Response(body = text.encode(

    "utf-8"))

    async def init(loop):

    app = web.Application(loop = loop)

    app.router.add_route("GET", "/", index)

    app.router.add_route("GET",

    "/hellp/{name}", hello)

    srv = await loop.create_server(app.make_handler(),

    "127.0.0.1", 8000)

    print(

    "Server started at http://127.0.0.1:8000..."

    )

    return srv

    loop = asyncio.get_event_loop()

    loop.run_until_complete(init(loop))

    loop.run_forever()

    四、current,futures

    1. python3新增的库

    2.类似其它语言的线程池的概念

    3.利用multiprocessing实现真正的并行计算(当然要求我们的CPU是多核的)

    4.核心原理:以子进程的形式,实现多个python解释器

    从而令python程序,可以利用多核CPU来提升执行速度。由于子进程于主解释器相分离,所以他们的全局解释器锁也是相互独立的,每个子进程都能完整的使用一个CPU内核

    5.concurrent.futures.Executor

    (1)ThreadPoolExecutor

    (2)ProcessPoolExecutor

    (3)执行的时候需要自行选择

    (4)submit(fn,args,kwargs)

    fn:异步执行的函数

    args,kwargs参数

    import time

    from concurrent.futures

    import ThreadPoolExecutor

    def return_future(msg):

    time.sleep(3)

    return msg

    # 创建一个线程池

    pool = ThreadPoolExecutor(max_workers =

    2)# 参数是2, 代表里面有两个线程干活

    # 往线程池里面加入两个task

    f1 = pool.submit(return_future, "hello")

    f2 = pool.submit(return_future, "world")

    time.sleep(1)

    # 等待执行完毕

    print(f1.done())

    time.sleep(3)

    print(f2.done())

    # 结果

    print(f1.result())

    print(f2.result())

    2019111383546382.jpg?2019101383617

    源码

    d28_1_asynchronization_examples.py

    https://github.com/ruigege66/Python_learning/blob/master/d28_1_asynchronization_examples.py

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

    本文标题: Python 异步协程函数原理及实例详解

    本文地址: http://www.cppcns.com/jiaoben/python/286053.html

    展开全文
  • 一,协同函数的定义和启动: –a.用coroutine.create创建一个协程 Co= coroutine.create(function() local c =a+b return c end ) –1.启动coroutine.create定义的函数 coroutine.resume(Co,20,30) b.用coroutine....
  • lua协程

    2019-11-30 11:35:52
    coroution协程 ...启动协程函数和继续运行,coroutine.resume(co,10,20) co = coroutine.wrap(function(a,b) end) 另一种创建协程函数方法,可co(10,20)这样启动协程函数 暂停协程函数,coroutine.yiel...
  • 首先承认这个系列有点标题党,Jetpack 的 MVVM 本身没有错...Flow 基于协程实现,具有丰富的操作符,通过这些操作符可以实现线程切换、处理流式数据,相比 LiveData 功能更加强大。 但唯有一点不足,无法像 LiveData ..
  • Unity协程与调用函数

    2020-10-29 18:13:31
    // 启动协程 Public Coroutine StartCoroutine(methodName:String); Public Coroutine StartCoroutine(IEnumertator rountine); Public Coroutine StartCoroutine(IEnumertator rountine,Object Value); //终止...
  • 从句法上看,协程与生成器类似,都是定义体中包含 yield 关键字的函数。可是,在协程中, yield 通常出现在表达式的右边(例如, datum = yield),可以产出值,也可以不产出 —— 如果 yield 关键字后面没有表达式...
  • 第二部分:使用体系结构组件启动协程(本文) Part III: LiveData and Coroutines patterns 第三部分:LiveData和协程模式 Jetpack’s Architecture Components provide a bunch of shortcuts so you don’t have to ...
  • 背景最近在做后端服务python到go的迁移和重构,这两种语言里,最大的特色和优势就是都支持协程。之前一直做python的性能优化和架构优化,一开始觉得两个协程原理和应用应该差不多,后来发现还是有很大的区别,今天就...
  • 面试被问到python3 的asyncio模块、python2中的yield和yield from的区别面的第一家觉得回答的不是很好, 回来进行收集整理一番,以便巩固记忆Python中的协程大概经历了三个阶段:最初的生成器变形yield/send引入@...
  • 文章目录一、前言二、延迟启动协程三、GlobalScope.async四、参考链接 一、前言 在之前的例子中,我们知道可以通过launch或者async来启动协程,并可以控制其生命周期,而且还知道了通过async的异步可以做到并行运行...
  • 1.简单启动协程Demo 本文例子代码地址:gitee.com/mcaotuman/k… 写个小demo,先记住怎么用,后面再分析源码。 三个挂起函数: 输出结果: 2.构建suspend修饰的lambda函数 2.1 suspend lambda 下面这段代码是...
  • 本文是我在 2019 年 Android 开发者峰会上与 Yigit Boyar 的谈话总结的第二部分。 ... 第一部分:响应式 UI 第二部分:使用架构组件启动协程(本文) ...这是启动协程最常见的方法之一,因为大多数数
  • 3.协程-挂起函数

    2021-05-31 14:42:56
    上一篇,我们知道了非阻塞挂起的核心是要执行一个挂起函数,挂起函数的作用就是启动线程执行耗时任务,耗时任务执行完毕,通知调用线程继续执行后续的代码。那么我们如何定义挂起函数呢?有哪些方式呢?接下来我们...
  • 1. 什么是协程 ...在 Python 中协程就是一个可以暂停执行的函数,听起来和生成器的概念一样。 ​ 从 Python3.4 开始协程被加入到标准库,当时的协程是通过 @asyncio.coroutine 和 yeild from 实现的,看起来和生
  • java初转kotlin 启动线程的写法: val myThread = thread { //do what you want } 这个 thread 方法有个参数 start 默认为 true,换句话说,这样创造出来的线程默认...协程启动其实与上面写的thead启动有相似的地
  • LUA协程

    2017-05-26 18:53:00
    一 LUA 协程函数 1resume local status, returnvs = coroutine.resume(co, params) co 为 所要启动的协程。 第一次调用resume时,参数是协程函数入口的参数,协程函数调用coroutine.yield之后交出控制权 后面...
  • 每个Go程序启动的时候只有一个对用户可见的协程,我们称之为主协程。一个协程可以开启更多其它新的协程。 在Go中,开启一个新的协程是非常简单的,我们只需要在一个函数调用之前使用一个go关键字,即可让此函数调用...
  • 协程

    千次阅读 2016-03-26 15:30:48
    子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕。所以子程序调用是通过栈实现的,一个线程只能在某一时刻执行一个子程序。...
  • ### 协程是什么? 首先kotlin协程是kotlin的扩展库(kotlinx.coroutines)。 上一篇我们简单了解了线程的概念,线程在Android开发中一般用来做一些复杂耗时的操作,避免耗时操作阻塞主线程而出现ANR的情况,例如...
  • Kotlin协程启动(2)

    2019-09-08 19:02:31
    在说协程启动之前来看看线程启动的代码: Thread { println("线程启动") }.start() 是不是和协程启动很像: GlobalScope.launch { println("test continuation start") } 其实很多时候都可以用线程的...
  • kotlin 协程启动Kotlin coroutines are an efficient way to (re)use threads while the computation has been moved somewhere else. Coroutines are bound to the concept of Scope: to run one, you need before ...
  • 协程就是用户空间的轻量线程,或者说是用户空间创建的伪线程,既然是创建了线程,就需要实现函数调用。简单来说,协程和线程切换的过程是类似的,只不过是用户空间实现的切换: _st_md_cxt_save:保存当前函数信息...
  • unity3d-IEnumerator协程

    2018-02-06 15:13:13
    使用 StartCoroutine(函数名())启动协程协程函数中yield return new WaitForSeconds(停留时间) 可是实现停留 如: public void Fun()//普通函数打印时间 { printf("Time.time");//打印时间 } 转化成协程...
  • launch:我们之前已经使用过了GlobalScope的launch来启动协程,它返回一个Job async:返回一个Deferred,它也是一个Job,但是可以使用await函数获得运行的结果 除了之前结构化并发中介绍的几种指定CoroutineScope的...
  • 协程_async 修饰函数_回调 #!user/bin/env python3 # -*- coding:utf-8 -*- # Email 23198899766@QQ.com # Time : 2021/3/14 13:17 import asyncio # async 修饰函数 async def request(url): print('正在请求...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,734
精华内容 6,693
关键字:

启动协程的函数