标签: coroutine

协同设计模式替代协同程序

目前,我有大量的C#计算(方法调用)驻留在将按顺序运行的队列中.每次计算都会使用一些高延迟服务(网络,磁盘......).

我打算使用Mono协程来允许计算队列中的下一次计算继续,而先前的计算正在等待高延迟服务返回.但是,我更喜欢不依赖Mono协同程序.

是否存在可在纯C#中实现的设计模式,这使我能够在等待高延迟服务返回时处理其他计算?

谢谢

更新:

我需要执行大量(> 10000)任务,每个任务都将使用一些高延迟服务.在Windows上,您无法创建那么多线程.

更新:

基本上,我需要一个设计模式来模拟Stackless Python(http://www.stackless.com/)中的tasklet的优点(如下所示)

  1. 巨大的任务数量
  2. 如果任务阻止队列中的下一个任务执行
  3. 没有浪费的cpu周期
  4. 任务之间的最小开销切换

c# mono continuations design-patterns coroutine

12
推荐指数
3
解决办法
4883
查看次数

在asyncio.Protocol.data_received中调用协同程序

asyncio.Protocol.data_received在新的Python asyncio模块的回调中执行异步操作时遇到问题.

考虑以下服务器:

class MathServer(asyncio.Protocol):

   @asyncio.coroutine
   def slow_sqrt(self, x):
      yield from asyncio.sleep(1)
      return math.sqrt(x)

   def fast_sqrt(self, x):
      return math.sqrt(x)

   def connection_made(self, transport):
      self.transport = transport

   #@asyncio.coroutine
   def data_received(self, data):
      print('data received: {}'.format(data.decode()))
      x = json.loads(data.decode())
      #res = self.fast_sqrt(x)
      res = yield from self.slow_sqrt(x)
      self.transport.write(json.dumps(res).encode('utf8'))
      self.transport.close()
Run Code Online (Sandbox Code Playgroud)

与以下客户一起使用:

class MathClient(asyncio.Protocol):

   def connection_made(self, transport):
      transport.write(json.dumps(2.).encode('utf8'))

   def data_received(self, data):
      print('data received: {}'.format(data.decode()))

   def connection_lost(self, exc):
      asyncio.get_event_loop().stop()
Run Code Online (Sandbox Code Playgroud)

随着self.fast_sqrt被召唤,一切都按预期工作.

self.slow_sqrt,它不起作用.

它也不适用self.fast_sqrt@asyncio.coroutine装饰器data_received.

我觉得我在这里缺少一些基本的东西.

完整的代码在这里: …

python network-programming yield coroutine python-asyncio

12
推荐指数
1
解决办法
3587
查看次数

如果coroutine使用asyncio引发异常,如何关闭循环和打印错误?

假设我有几个协程在循环中运行.如何使得如果其中一些失败而异常整个程序会因此异常而失败?因为现在asyncio甚至不打印来自协程的错误消息,除非我使用日志级别"DEBUG".

from asyncio import get_event_loop, sleep


async def c(sleep_time=2, fail=False):
    print('c', sleep_time, fail)
    if fail:
        raise Exception('fail')
    while True:
        print('doing stuff')
        await sleep(sleep_time)



loop = get_event_loop()
loop.create_task(c(sleep_time=10, fail=False))
loop.create_task(c(fail=True))
loop.run_forever()
Run Code Online (Sandbox Code Playgroud)

python coroutine python-asyncio

12
推荐指数
2
解决办法
4444
查看次数

Kotlin协程如何知道何时进行网络呼叫?

我是Kotlin协同程序的新手,有一点我没想到的是,协同程序如何知道在进行网络调用时何时屈服于其他人.

如果我理解正确的话,协同程序会先发制人地工作,这意味着当它执行一些耗时的任务(通常是I/O操作)时,它知道何时屈服于其他协同程序.

例如,假设我们想绘制一些将显示来自远程服务器的数据的UI,并且我们只有一个线程来安排我们的协同程序.我们可以启动一个协程来进行REST API调用以获取数据,同时让另一个协同程序绘制UI的其余部分,它们不依赖于数据.但是,由于我们只有一个线程,因此一次只能运行一个协程.除非用于获取数据的协程在等待数据到达时抢先获取,否则两个协同程序将按顺序执行.

据我所知,Kotlin的协程实现并没有修补任何现有的JVM实现或JDK网络库.因此,如果协程正在调用REST API,它应该像使用Java线程一样阻止.我这样说是因为我在python中看起来有类似的概念,叫做绿色线程.为了使它能够与python的内置网络库一起工作,必须首先对网络库进行"猴子修补".对我而言,这是有道理的,因为只有网络库本身知道何时屈服.

那么,任何人都可以解释Kotlin协程如何知道何时调用阻塞Java网络API?或者如果没有,那么它是否意味着上面例子中提到的任务无法同时执行给出单个线程?

谢谢!

java coroutine kotlin kotlin-coroutines

12
推荐指数
1
解决办法
2435
查看次数

将 Coroutine 调用放在 Repository 或 ViewModel 中哪个更好?

只是想知道其他人的意见我有两种方法可以做某事并且很好奇哪个更好(希望你为什么这么认为)

我有 2 个文件 WordRepository 和 WordViewModel。我可以在 Repo 或 ViewModel 中以两种方式执行协程,但希望有人能告诉我为什么我会在其中一个或另一个中执行协程,反之亦然。

版本 A.(协程在 Repo 中的位置)

WordRepo:

class WordRepository(private val wordDao: WordDao): WordRepo {

    @WorkerThread
    override suspend fun deleteAllLogsOlderThan(XDays: Int): Int = withContext(IO) {
        return@withContext wordDao.deleteAll()
    }

}

WordViewModel:

class WordViewModel(private val wordRepository: WordRepo) : ViewModel() {

    fun deleteAllLogsOlderThanA(XDays:Int): Int = runBlocking {
        wordRepository.deleteAllLogsOlderThan(XDays)
    }

}
Run Code Online (Sandbox Code Playgroud)

版本 B.(协程在 ViewModel 中的位置)

Word Repo:
class WordRepository(private val wordDao: WordDao): WordRepo {

    @WorkerThread
    override suspend fun deleteAllLogsOlderThan(XDays: Int): Int = wordDao.deleteAll()

}

WordViewModel:
class …
Run Code Online (Sandbox Code Playgroud)

android mvvm coroutine kotlin android-room

12
推荐指数
1
解决办法
2016
查看次数

是否有必要在 std::coroutine_handle 上调用 destroy ?

std::coroutine_handle是C ++ 20的新协程的一个重要部分。例如,发电机经常(总是?)使用它。在我见过的所有示例中,在协程的析构函数中手动销毁句柄:

struct Generator {
    // Other stuff...
    std::coroutine_handle<promise_type> ch;

    ~Generator() {
        if (ch) ch.destroy();
    }
}
Run Code Online (Sandbox Code Playgroud)

这真的有必要吗?如果是的话,为什么没有这个已经被完成的coroutine_handle,是有一个RAII版本coroutine_handle,其行为这种方式,并会如果我们忽略了发生什么destroy电话?

例子:

  1. https://en.cppreference.com/w/cpp/coroutine/coroutine_handle(感谢 463035818_is_not_a_number
  2. C++20 标准也在 9.5.4.10 Example 2(在 N4892 上检查)中提到它。
  3. (德语)https://www.heise.de/developer/artikel/Ein-unendlicher-Datenstrom-dank-Coroutinen-in-C-20-5991142.html
  4. https://www.scs.stanford.edu/~dm/blog/c++-coroutines.html - 提到如果不调用它会泄漏,但没有引用标准中的段落或为什么不引用在 的析构函数中调用std::coroutine_handle

c++ coroutine c++20

12
推荐指数
1
解决办法
269
查看次数

Coroutines和`goto`之间的区别?

我总是读到"goto"的可怕之处.但今天,阅读有关谷歌编程语言Go的消息,我看到它支持Coroutines(Goroutines).

问题是:

Coroutine == GoTo 
Run Code Online (Sandbox Code Playgroud)

要么

Coroutine != GoTo?
Run Code Online (Sandbox Code Playgroud)

为什么?

goto go coroutine goroutine

11
推荐指数
2
解决办法
2053
查看次数

Lua ::如何编写将加载多个CPU的简单程序?

我无法在Lua中编写一个可以加载多个CPU的程序.由于Lua 通过协同程序支持这个概念,我相信它是可以实现的.

我失败的原因可能是:

  • 这在Lua是不可能的
  • 我不能写它☺(希望是这样的)

更有经验的人(我两周前发现Lua)可以指出我正确的方向吗?


The point is to write a number-crunching script that does hi-load on ALL cores... 为了Lua的权力的示范目的.

谢谢...

lua multithreading multicore coroutine

11
推荐指数
2
解决办法
1万
查看次数

在Python生成器中是否有类似"self"的东西?

有没有办法在生成器的定义中获取对返回的生成器对象的引用?这类似于self传递给__next__迭代器方法内部方法的参数.浏览Python的文档后,我没有找到类似的东西.

这个问题出现的时候,我正在探索以下论文的大部分内容,我可以使用生成器作为协同程序在Python中实现.论文:http://citeseerx.ist.psu.edu/viewdoc/summary?doi = 10.1.1.19.79

我能做的最接近的是使用装饰器,它建立在David Beazley的coroutine装饰上,但感觉有点像黑客.

from functools import wraps


def coroutine(func):
    @wraps(func)
    def decorated(*args, **kwargs):
        f = func(*args, **kwargs)
        next(f)
        f.send(f)
        return f
    return decorated


@coroutine
def A():
    self = yield
    # do stuff...
Run Code Online (Sandbox Code Playgroud)

编辑:基于下面的答案,下面的类可以用作装饰器,让生成器接收self作为其第一个参数的引用.它具有额外的好处,任何用它装饰的发电机都具有这种类型coroutine.

class coroutine(object):
    """Decorator class for coroutines with a self parameter."""
    def __new__(cls, func):
        @wraps(func)
        def decorated(*args, **kwargs):
            o = object.__new__(cls)
            o.__init__(func, args, kwargs)
            return o
        return decorated

    def __init__(self, generator, args, …
Run Code Online (Sandbox Code Playgroud)

python coroutine

11
推荐指数
1
解决办法
713
查看次数

动态添加Python asyncio的事件循环应该执行的列表

我有一个函数download_all,它遍历一个硬编码的页面列表,按顺序下载它们.但是如果我想根据页面的结果动态添加到列表中,我该怎么办呢?例如,下载第一页,解析它,并根据结果将其他页面添加到事件循环中.

@asyncio.coroutine
def download_all():
    first_page = 1
    last_page = 100
    download_list = [download(page_number) for page_number in range(first_page, last_page)]
    gen = asyncio.wait(download_list)
    return gen

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

python asynchronous coroutine python-asyncio

11
推荐指数
2
解决办法
4938
查看次数