我正在尝试使用boost::asio::spawn协同程序重写项目.项目的某些部分无法更改.例如,存储协议库也是用boost::asio但没有协同程序编写的.
问题是如何转换yield_context为普通回调(boost::function对象或经典仿函数).
这就是我们在存储库API中的含义:
void async_request_data(uint64_t item_id, boost::function< void(Request_result *) > callback);
Run Code Online (Sandbox Code Playgroud)
正如我们从示例中所知,asio yield上下文可以像这样使用:
my_socket.async_read_some(boost::asio::buffer(data), yield);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,boost::asio::yield_context对象充当async_read_some的回调.我想传递一个yield对象作为第二个参数async_request_data,所以我可以以同步的方式使用它.
如何才能做到这一点?我认为可能通过一些代理对象,可能使用基于asio_handler_invoke的方法.但我很难看到如何做到这一点.
我正在使用asyncio作为网络框架.
在下面的代码中(low_level是我们的低级函数,mainblock是我们的程序入口,user_func是用户定义的函数):
import asyncio
loop = asyncio.get_event_loop()
""":type :asyncio.AbstractEventLoop"""
def low_level():
yield from asyncio.sleep(2)
def user_func():
yield from low_level()
if __name__ == '__main__':
co = user_func()
loop.run_until_complete(co)
Run Code Online (Sandbox Code Playgroud)
我想包装low_level正常函数而不是coroutine(compatibility等等),但是low_level在事件循环中.如何将其包装为正常功能?
我正在从onCreate(...)调用暂停的函数
override fun onCreate(savedInstanceState: Bundle?) {
...
...
callGetApi()
}
Run Code Online (Sandbox Code Playgroud)
暂停功能为:
suspend fun callGetApi() {....}
Run Code Online (Sandbox Code Playgroud)
但是错误显示挂起函数“ callGetApi”应仅从协程或另一个挂起函数调用
目前,我有大量的C#计算(方法调用)驻留在将按顺序运行的队列中.每次计算都会使用一些高延迟服务(网络,磁盘......).
我打算使用Mono协程来允许计算队列中的下一次计算继续,而先前的计算正在等待高延迟服务返回.但是,我更喜欢不依赖Mono协同程序.
是否存在可在纯C#中实现的设计模式,这使我能够在等待高延迟服务返回时处理其他计算?
谢谢
更新:
我需要执行大量(> 10000)任务,每个任务都将使用一些高延迟服务.在Windows上,您无法创建那么多线程.
更新:
基本上,我需要一个设计模式来模拟Stackless Python(http://www.stackless.com/)中的tasklet的优点(如下所示)
我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.
我觉得我在这里缺少一些基本的东西.
完整的代码在这里: …
根据这个最新的C++ TS:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4628.pdf,基于对C#async/await语言支持的理解,我是想知道什么是C++协同程序的"执行上下文"(从C#借来的术语)?
我在Visual C++ 2017 RC中的简单测试代码表明,协同程序似乎总是在线程池线程上执行,并且很少控制应用程序开发人员可以执行协同程序的线程上下文 - 例如,应用程序是否可以强制执行所有协同程序(用编译器生成的状态机代码)只在主线程上执行,而不涉及任何线程池线程?
在C#中,SynchronizationContext是一种指定"上下文"的方法,其中所有协程"一半"(编译器生成的状态机代码)将被发布并执行,如以下文章所示:https://blogs.msdn.microsoft.com/pfxteam/2012/01/20/await-synchronizationcontext-and-console-apps /,而Visual C++ 2017 RC中的当前协程实现似乎总是依赖于并发运行时,它默认执行生成的状态机代码线程池线程.是否有类似的同步上下文概念,用户应用程序可以使用它来将协同程序执行绑定到特定的线程?
另外,在Visual C++ 2017 RC中实现的协同程序的当前默认"调度程序"行为是什么?即1)如何准确指定等待条件?2)当满足等待条件时,谁调用暂停的协程的"下半部分"?
关于C#中任务调度的我(天真)猜测是C#"完全"通过任务继续"实现"等待条件 - 等待条件由TaskCompletionSource拥有的任务合成,并且任何需要等待的代码逻辑将被链接为继续因此,如果满足等待条件,例如,如果从低级网络处理程序接收到完整消息,则它执行TaskCompletionSource.SetValue,它将基础任务转换为已完成状态,从而有效地允许链式连续逻辑开始执行(将任务从先前创建的状态置于就绪状态/列表中) - 在C++协程中,我推测std :: future和std :: promise将被用作类似的机制(std :: future是任务,而std :: promise是TaskCompletionSource,用法也非常相似!) - C++协同调度程序(如果有的话)依赖于某种类似的机制来执行行为吗?
[编辑]:在做了一些进一步的研究后,我能够编写一个非常简单但非常强大的抽象代码,称为awaitable,支持单线程和协作式多任务处理,并具有一个简单的基于thread_local的调度程序,它可以在根协同程序的线程上执行协同程序开始了.代码可以在这个github repo中找到:https://github.com/llint/Awaitable
等待是可组合的,它在嵌套级别维护正确的调用排序,并且它具有原始的让步,定时等待和从其他地方设置就绪,并且可以从中导出非常复杂的使用模式(例如只有无限循环协程当某些事件发生时被唤醒),编程模型紧跟C#Task async/await模式.请随时提供反馈.
我是Kotlin协同程序的新手,有一点我没想到的是,协同程序如何知道在进行网络调用时何时屈服于其他人.
如果我理解正确的话,协同程序会先发制人地工作,这意味着当它执行一些耗时的任务(通常是I/O操作)时,它知道何时屈服于其他协同程序.
例如,假设我们想绘制一些将显示来自远程服务器的数据的UI,并且我们只有一个线程来安排我们的协同程序.我们可以启动一个协程来进行REST API调用以获取数据,同时让另一个协同程序绘制UI的其余部分,它们不依赖于数据.但是,由于我们只有一个线程,因此一次只能运行一个协程.除非用于获取数据的协程在等待数据到达时抢先获取,否则两个协同程序将按顺序执行.
据我所知,Kotlin的协程实现并没有修补任何现有的JVM实现或JDK网络库.因此,如果协程正在调用REST API,它应该像使用Java线程一样阻止.我这样说是因为我在python中看起来有类似的概念,叫做绿色线程.为了使它能够与python的内置网络库一起工作,必须首先对网络库进行"猴子修补".对我而言,这是有道理的,因为只有网络库本身知道何时屈服.
那么,任何人都可以解释Kotlin协程如何知道何时调用阻塞Java网络API?或者如果没有,那么它是否意味着上面例子中提到的任务无法同时执行给出单个线程?
谢谢!
假设我们有
cppcoro::generator<int> gen_impl(int in) {
const auto upper = in + 10;
for (; in < upper; ++in)
co_yield in;
}
cppcoro::generator<cppcoro::generator<int>> gen() {
for (int n = 1; n < 100; n += 10)
co_yield gen_impl(n);
}
Run Code Online (Sandbox Code Playgroud)
所以我们可以很好地迭代内部范围
for (auto&& row : gen() ) {
for (auto n : row)
std::cout << n << ' ';
std::cout << '\n';
}
Run Code Online (Sandbox Code Playgroud)
注意:范围是for ref是必需的,因为cppcoro::generator不允许复制(删除的副本ctor)
打印
1 2 3 4 5 6 7 8 9 10
11 12 13 14 …Run Code Online (Sandbox Code Playgroud) 只是想知道其他人的意见我有两种方法可以做某事并且很好奇哪个更好(希望你为什么这么认为)
我有 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) 的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电话?
例子:
std::coroutine_handle。coroutine ×10
c++ ×4
kotlin ×3
android ×2
python ×2
android-room ×1
async-await ×1
boost ×1
boost-asio ×1
c# ×1
c++20 ×1
generator ×1
java ×1
mono ×1
mvvm ×1
python-3.x ×1
range-v3 ×1
yield ×1