根据最新的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#中,任务调度的等待条件纯粹是通过任务继续完成实现的——通过一个TaskCompletionSource拥有的任务来合成等待条件,任何需要等待的代码逻辑都将链接到它作为继续,因此,如果等待条件得到满足,例如从底层网络处理程序接收到完整的消息,则会执行TaskCompletionSource.SetValue,这将把底层任务转换为已完成状态,有效地允许链接的继续逻辑开始执行(将任务从先前创建的状态放入就绪状态/列表)——在C++协程中,我推测std::future和std::promise将被用作类似的机制(std::future作为任务,而std::promise作为TaskCompletionSource,使用方式也非常相似!)——因此,C++协程调度器(如果有的话)是否依赖于某些类似的机制来执行行为?
[编辑]:经过进一步研究,我能够编写一个非常简单但非常强大的抽象,称为awaitable,支持单线程和协作式多任务处理,并具有基于thread_local的简单调度器,可以在启动根协程的线程上执行协程。代码可以在此github repo找到:https://github.com/llint/Awaitable awaitable可以按嵌套级别维护正确的调用顺序,它具有原始的yielding、定时等待和从其他地方设置ready的特性,非常复杂的使用模式可以从中派生出来(例如只有在发生某些事件时才会被唤醒的无限循环协程),编程模型紧密遵循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#中,任务调度的等待条件纯粹是通过任务继续完成实现的——通过一个TaskCompletionSource拥有的任务来合成等待条件,任何需要等待的代码逻辑都将链接到它作为继续,因此,如果等待条件得到满足,例如从底层网络处理程序接收到完整的消息,则会执行TaskCompletionSource.SetValue,这将把底层任务转换为已完成状态,有效地允许链接的继续逻辑开始执行(将任务从先前创建的状态放入就绪状态/列表)——在C++协程中,我推测std::future和std::promise将被用作类似的机制(std::future作为任务,而std::promise作为TaskCompletionSource,使用方式也非常相似!)——因此,C++协程调度器(如果有的话)是否依赖于某些类似的机制来执行行为?
[编辑]:经过进一步研究,我能够编写一个非常简单但非常强大的抽象,称为awaitable,支持单线程和协作式多任务处理,并具有基于thread_local的简单调度器,可以在启动根协程的线程上执行协程。代码可以在此github repo找到:https://github.com/llint/Awaitable awaitable可以按嵌套级别维护正确的调用顺序,它具有原始的yielding、定时等待和从其他地方设置ready的特性,非常复杂的使用模式可以从中派生出来(例如只有在发生某些事件时才会被唤醒的无限循环协程),编程模型紧密遵循C#任务异步/等待模式。请随意提供您的反馈。