标签: coroutine

协同程序有什么好处?

我一直在学习一些用于游戏开发的lua.我听说过其他语言的协同程序,但是真的在lua中找到了它们.我只是不明白它们有多有用,我听到很多人都在谈论如何做一个多线程的东西,但是它们不是按顺序运行的吗?那么顺序运行的普通函数会带来什么好处呢?我只是没有得到它们与函数有多么不同,只是它们可以暂停并让另一个运行一秒钟.似乎用例场景对我来说不会那么大.

任何人都想清楚为什么有人会从中受益?

特别是从游戏编程角度来看,洞察力会很好^^

lua multithreading coroutine

9
推荐指数
2
解决办法
4470
查看次数

安全的跨平台协同程序

我遇到的所有协程实现都使用汇编或检查内容jmp_buf.这个问题是它本身不是跨平台的.

我认为以下实现不会进入未定义的行为或依赖于实现细节.但我从来没有遇到像这样写的协程.

是否有一些固有的缺陷是使用线程跳远?
这段代码中有一些隐藏的问题吗?

#include <setjmp.h>
#include <thread>

class Coroutine
{
public:
   Coroutine( void ) :
      m_done( false ),
      m_thread( [&](){ this->start(); } )
   { }

   ~Coroutine( void )
   {
      std::lock_guard<std::mutex> lock( m_mutex );

      m_done = true;
      m_condition.notify_one();

      m_thread.join();
   }

   void start( void )
   {
      if( setjmp( m_resume ) == 0 )
      {
         std::unique_lock<std::mutex> lock( m_mutex );
         m_condition.wait( lock, [&](){ return m_done; } );
      }
      else
      {
         routine();
         longjmp( m_yield, 1 );
      }
   }

   void resume( void ) …
Run Code Online (Sandbox Code Playgroud)

c++ cross-platform coroutine c++11

9
推荐指数
2
解决办法
6008
查看次数

如何从python中的coroutine获取返回值

我正在根据http://www.dabeaz.com/coroutines/Coroutines.pdf尝试coroutines管道

问题是,我怎样才能从中获取价值sink而不仅仅是打印它?

以此代码为例

def coroutine(func):
    def start(*args, **kwargs):
        cr = func(*args, **kwargs)
        next(cr)
        return cr
    return start


@coroutine
def produce(target):
    while True:
        n = (yield)
        target.send(n*10)


@coroutine
def sink():
    try:
        while True:
            n = (yield)
            print(n)
    except GeneratorExit:
        pass


sk = sink()
pipe = produce(sink())
Run Code Online (Sandbox Code Playgroud)

使用此代码,我得到:

>>> pipe.send(10)
100
Run Code Online (Sandbox Code Playgroud)

然后我想得到返回值而不是打印它,我试图从接收器中产生:

@coroutine
def sink():
    try:
        while True:
            yield (yield)
    except GeneratorExit:
        pass
Run Code Online (Sandbox Code Playgroud)

但它似乎不起作用,pipe.send(10)仍然返回None而不是发电机.

那么如何获得返回值呢?

python generator coroutine

9
推荐指数
1
解决办法
4630
查看次数

来自异步生成器的asyncio as_yielded

我希望能够从许多异步协同程序中获益.Asyncio as_completed有点接近我正在寻找的东西(即我希望任何协同程序能够随时返回到调用者然后继续),但这似乎只允许常规协同程序返回一次.

这是我到目前为止所拥有的:

import asyncio


async def test(id_):
    print(f'{id_} sleeping')
    await asyncio.sleep(id_)
    return id_


async def test_gen(id_):
    count = 0
    while True:
        print(f'{id_} sleeping')
        await asyncio.sleep(id_)
        yield id_
        count += 1
        if count > 5:
            return


async def main():
    runs = [test(i) for i in range(3)]

    for i in asyncio.as_completed(runs):
        i = await i
        print(f'{i} yielded')


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()
Run Code Online (Sandbox Code Playgroud)

替换runs = [test(i) for i in range(3)]runs = [test_gen(i) for i …

python coroutine control-flow async-await python-asyncio

9
推荐指数
1
解决办法
638
查看次数

为什么以及何时使用Kotlin在Android中使用协同例程代替线程,因为没有并行性?

我正在经历共同惯例的概念,以及它在kotlin中的使用和实现.

我用Google搜索并阅读了几个答案,就其在架构和性能方面与线程的不同之处而言.

这里解释得很好,

"coroutine"和"thread"之间的区别?

很公平,合作例程很棒,没有内存开销,性能卓越,没有死锁,竞争条件等等,而且易于使用.

现在,这里有一些事情,我很困惑,并希望更清楚 -

  1. 什么时候应该在Android中使用协同例程和线程?或者我应该坚持只是合作惯例?
  2. 如果,我只是坚持使用协同例程,那么它将如何利用CPU核心,因为它在单个线程上运行.

协同例程很好用,但它如何利用多个内核来提高性能.

android coroutine kotlin kotlin-coroutines

9
推荐指数
1
解决办法
709
查看次数

放弃协同程序

在Lua 5.1中,从不让协程正常结束有多糟糕?换句话说,如果一个协程收益但是我从来没有恢复它,它是否会在程序完成之前留下很多州?

cor=coroutine.wrap(somefunc)

while true do
   done=cor()
   if done then -- coroutine exited with "return true" 
       break
   else -- coroutine yielded with "coroutine.yield(false)"
       if some_condition then break end
   end
end

function somefunc()
    -- do something
    coroutine.yield(false)
    -- do some more
    return true
end 
Run Code Online (Sandbox Code Playgroud)

根据上面伪代码中的some_condition,协程可能永远不会被恢复,因此可能永远不会正确地"结束".

我可以这样做几十个协同程序而不必担心吗?将协同程序置于此状态是否安全?这个很贵吗?

lua coroutine

8
推荐指数
1
解决办法
3048
查看次数

协同程序的替代品

此示例已用于另一个问题,以说明协同程序如何用于编写视频游戏中的过场动画:

bob.walkto(jane)
bob.lookat(jane)
bob.say("How are you?")
wait(2)
jane.say("Fine")
...
Run Code Online (Sandbox Code Playgroud)

每个函数产生主动引擎,它在恢复协程之前进行动画,定时等.协程的可能替代方案是事件队列而不是代码,但是必须实现控制逻辑和循环作为事件.是否有其他可用于实现此类功能的协同程序的替代方案?我见过一些文章中提到的回调,但我不确定代码的外观.

coroutine

8
推荐指数
1
解决办法
2260
查看次数

避免在python增强型生成器中"忽略异常"

我在python中有一个协程(增强型生成器),在数据结束后要执行一些代码:

def mycoroutine():
  try:
    while True:
      data = (yield)
      print data
  finally:
    raise ValueError
    print "END"

co = mycoroutine()
co.next()

for i in (1,2,3):
  co.send(i)
Run Code Online (Sandbox Code Playgroud)

ValueError异常没有提出,但解释简单地打印:

Exception ValueError: ValueError() in <generator object mycoroutine at 0x2b59dfa23d20> ignored
Run Code Online (Sandbox Code Playgroud)

有没有办法在调用者中捕获异常?

python exception generator coroutine

8
推荐指数
1
解决办法
6610
查看次数

Lua coroutines - setjmp longjmp clobbering?

在不久前的博客文章中,Scott Vokes描述了与lua使用C函数实现协程相关的技术问题,setjmp并且longjmp:

Lua协同程序的主要限制是,由于它们是用setjmp(3)和longjmp(3)实现的,所以你不能用它们从Lua调用C代码调用回调用回调用C的Lua,因为嵌套的longjmp将破坏C函数的堆栈帧.(这是在运行时检测到的,而不是静默失败.)

我没有发现这在实践中是一个问题,我不知道有什么方法可以修复它而不损坏Lua的可移植性,这是我最喜欢的Lua之一 - 它几乎可以运行任何ANSI C编译器和适度的空间.使用Lua意味着我可以轻装上阵.:)

我已经使用了很多协同程序,我认为我已经广泛地理解了发生了什么setjmp,longjmp做了什么和做了什么,但是我在某个时候读到了它,并意识到我并没有真正理解它.为了弄明白这一点,我尝试制作一个我认为应该根据描述引起问题的程序,相反它似乎工作正常.

然而,我看到其他一些地方人们似乎声称存在问题:

问题是:

  • 在什么情况下,由于C函数堆栈框架遭到破坏,lua协同程序无法工作?
  • 到底是什么结果?"在运行时检测到"是否意味着,lua恐慌?或者是其他东西?
  • 这是否仍会影响lua(5.3)的最新版本,或者这实际上是5.1问题还是什么?

这是我制作的代码.在我的测试中,它与lua 5.3.1链接,编译为C代码,测试本身在C++ 11标准下编译为C++代码.

extern "C" {
#include <lauxlib.h>
#include <lua.h>
}

#include <cassert>
#include <iostream>

#define CODE(C) \
case C: { \
  std::cout << "When returning to " << where << " got code '" #C "'" << std::endl; \
  break; \
}

void handle_resume_code(int code, const char * where) {
  switch (code) {
    CODE(LUA_OK) …
Run Code Online (Sandbox Code Playgroud)

c c++ lua coroutine longjmp

8
推荐指数
1
解决办法
1286
查看次数

修改延期结果

给定一个返回模型的API(由Retrofit实现).我将一个老式的Call包含在一个Deferred使用extention函数中:

fun <T> Call<T>.toDeferred(): Deferred<T> {
    val deferred = CompletableDeferred<T>()

    // cancel request as well
    deferred.invokeOnCompletion {
        if (deferred.isCancelled) {
            cancel()
        }
    }

    enqueue(object : Callback<T> {
        override fun onFailure(call: Call<T>?, t: Throwable) {
            deferred.completeExceptionally(t)
        }

        override fun onResponse(call: Call<T>?, response: Response<T>) {
            if (response.isSuccessful) {
                deferred.complete(response.body()!!)
            } else {
                deferred.completeExceptionally(HttpException(response))
            }
        }
    })

    return deferred
}
Run Code Online (Sandbox Code Playgroud)

现在我可以得到这样的模型:

data class Dummy(val name: String, val age: Int)

fun getDummy(): Deferred<Dummy> = api.getDummy().toDeferred()
Run Code Online (Sandbox Code Playgroud)

但是如何修改里面的对象 …

coroutine kotlin rx-java2 kotlin-coroutines

8
推荐指数
1
解决办法
2537
查看次数