- 论坛徽章:
- 1
|
本人用C语言在x86上实现了类似于C#的async await异步操作。
(windows使用setthreadcontext\getthreadcontext实现,linux用POSIX的ucontext.h下的函数实现。)
我已准备将其用于公司的项目。在此之前,我想听听各位的意见。这种做法在实现(网络)业务协议时非常方便,
不必维护“状态机”(自动机),而是在一个函数的流程里解决问题。但是,弊端呢? 除了浪费一点内存(我很快要移植到x64,我相信进程内存空间限制不是问题),
还有wp8的一点移植性问题,以及调试可能不太方便。除此之外的弊端还有什么?
以前没看到这个帖子,觉得有点想说的,针对原贴主。首先Windows上这么实现肯定是不行的,不是不能工作,是效率太差,还会有其他的问题。windows fiber也不好,不要用
ms自己都不用,只在早版本的sql server engine里面有过,不知道现在还有没有。coroutine也没什么用。async + message queue dispatch + ums(user mode scheduling)。
async_create() => create一个async task, 可以把它当成一个async io, 有个context, context 有 exec callack (相当于async_procedure).
async_post_work() => post work item to work queue, work queue pump the work item and dispatch to thread pool, work thread exec the work item
async_wait() => pump the message queue to check whether the work item is completed (whether context is posted back with result)
这里主要的问题是如果work item block 怎么办? coroutine 需要 work item YIELD, 对cpu bound的问题不大,如果work item 有io (尤其UNIX/LINUX 主要是sync io)
的话会block work thread, thread pool size会很大。setthreadcontext对一个pending在kernel的thread没用, 只对跑在user mode的时候有用,换句话说只在user mode cpu bound的
时候才有用。win7/2008 r2有个功能叫UMS(user mode scheduling), 在一个thread被block的时候 kernel会callback 你定义的一个函数,blocked thread 被release
之后,你会得到一个通知,你dequeue这个通知可以继续调度原先的work item。这是很关键的一点。普通coroutine被bind到一个thread之后,如果被block,你是没办法知道的。但是这仍然解决不了
被blocked的thread不能被利用的问题,有一个tricky的办法是拦截所有的blocking call, 转化成异步的syscall, 得到completion notification之后再调度到原来的work item, 可以以很少的thread支持大规模并发io,不管是同步还是异步。对原来的code,甚至第三方code完全透明。也不知道切不切题,啰嗦了不少。最近也在想这方面的问题。windows上可以利用concurrent runtime library(内部UMS支持)更方便。还有如果你suspend一个thread, 如果那个thread持有lock, 其他thread可以被block. 所以除非你非常清楚work item的code path,这是个危险的api. |
|