免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 14108 | 回复: 90

[C] 寻求建议,关于异步编程 [复制链接]

论坛徽章:
0
发表于 2014-12-17 12:01 |显示全部楼层
本人用C语言在x86上实现了类似于C#的async await异步操作。

(windows使用setthreadcontext\getthreadcontext实现,linux用POSIX的ucontext.h下的函数实现。)

我已准备将其用于公司的项目。

在此之前,我想听听各位的意见。

这种做法在实现(网络)业务协议时非常方便,不必维护“状态机”(自动机),而是在一个函数的流程里解决问题。

但是,弊端呢? 除了浪费一点内存(我很快要移植到x64,我相信进程内存空间限制不是问题),还有wp8的一点移植性问题,以及调试可能不太方便。

除此之外的弊端还有什么?

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
发表于 2014-12-17 13:48 |显示全部楼层
除了你说的那几点没什么其它弊端,这里有几个人都在做类似的事,包括我

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
发表于 2014-12-17 14:30 |显示全部楼层
本帖最后由 yulihua49 于 2014-12-17 14:31 编辑
windoze 发表于 2014-12-17 13:48
除了你说的那几点没什么其它弊端,这里有几个人都在做类似的事,包括我

在这讨论咱们那个问题,比原来那个帖子里强。
我那个架构程序已经写成,与发表的源码,有些修改。
现在正在试验,一般情况没问题。现在是想办法让程序进入fiber状态。一般情况进不去那个状态。
我很担心保存和恢复栈帧会出问题。

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
发表于 2014-12-17 14:40 |显示全部楼层
本帖最后由 yulihua49 于 2014-12-17 15:17 编辑
codechurch 发表于 2014-12-17 12:01
本人用C语言在x86上实现了类似于C#的async await异步操作。

(windows使用setthreadcontext\getthreadco ...

这两天正在弄这个,希望看看你的做法。
http://bbs.chinaunix.net/thread-4159120-6-1.html

  1. /*************************************************
  2. * char * set_sp(char *last_fiber_stack)
  3. * last_fiber_stack  -> %rdi
  4. ************************************************/

  5. .globl set_sp
  6.         .type   set_sp, @function
  7. set_sp:
  8. .LFB0:
  9.         .cfi_startproc
  10. //保存返址
  11.         movq    8(%rsp),%rax
  12.         movq    %rax,(%rdi)
  13. //计算rbp与rsp的距离
  14.         movq    %rbp,%rax
  15.         subq    %rsp,%rax
  16. //设定sp到fiber栈
  17.         movq    %rdi,%rbp
  18.         subq    $8,%rbp
  19.         movq    %rbp,%rsp
  20. //新的rbp,距离rsp与原来相同
  21.         addq    %rax,%rbp
  22.         movq    %rdi, %rax
  23.         ret
  24.         .cfi_endproc
  25. .LFE0:
  26.         .size   set_sp, .-set_sp
  27.         .p2align 4,,15
  28. .globl restore_sp
  29. /***********************************************************************
  30. * char *restore_sp(char *to,char *from,unsigned long BP,unsigned ling size)
  31. * to -> %rdi,from -> %rsi(没有使用), BP->%rdi,size->%rcx
  32. * to,就是在同一个线程,调度器底部,就是应用的栈顶。
  33. * 不拷贝数据,将来考虑从%rsi反向拷贝size字节到%sdi
  34. * std
  35. * rep movsb  -- 字节拷贝,效率?能保证两边都是8字节对齐?
  36. * cld
  37. ************************************************************************
  38.         .type   restore_sp, @function
  39. restore_sp:
  40. .LFB1:
  41.         .cfi_startproc
  42. //从栈顶拉出一个空间
  43.         movq    %rdi,%rax
  44.         subq    %rcx,%rax
  45. //返址设定
  46.         movq    8(%rsp),%rbx
  47.         movq    %rbx,(%rax)
  48.         subq    $8,%rax
  49. //rsp设定到新位置
  50.         movq    %rax,%rsp
  51. //设定rbp
  52.         movq    %rdx,%rbp
  53. //返回栈底
  54.         addq    $8,%rax
  55.         ret
  56.         .cfi_endproc
  57. .LFE1:
  58.         .size   restore_sp, .-restore_sp
  59.         .ident  "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-3)"
  60.         .section        .note.GNU-stack,"",@progbits
复制代码
两个asm函数。

论坛徽章:
0
发表于 2014-12-17 14:57 |显示全部楼层
回复 4# yulihua49


     我实现的接口是这样的:

extern async_t      async_create( u_long , bool , procedure_t , void * );
extern u_long       async_procedure( async_t );
extern bool           async_exec( async_t , bool );
extern int             async_wait( mt_object * , u_long );

async_create: 建立异步过程上下文(协程)。  其中 procedure_t 是用户实现的函数。  u_long 是栈尺寸, bool 是指示线程池的一个flags,void*是用户函数的参数。

async_procedure: 在当前线程执行异步过程。

async_exec:  从线程池分配一个线程执行  async_procedure 及协程 。

async_wait  : 异步等待事件,此函数必须在 异步过程 内部调用,调用此函数后,  async_procedure 返回。

async_wait  函数有超时参数,切换上下文之前要设定timer, 如果timer事件发生,则async_exec,从线程池找线程继续执行协程。 如果不超时,则从事件回调线程里执行协程。



论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
发表于 2014-12-17 15:15 |显示全部楼层
本帖最后由 windoze 于 2014-12-17 15:22 编辑

回复 5# codechurch

说实话我不是特别明白async/await到底有什么特别的用途,在我看来,就这个功能点而言一个线程池+packaged_task/future组合好像效果是一样的,而且不需要用coroutine倒腾stack。

Boost.thread里的future现在支持then和wait_all/wait_any,你可以把程序用future.wait().then(...).then(...)这样串起来。

这样会像Node.JS一样反人类的把程序切碎成一堆小函数,但async/await其实也得切……

论坛徽章:
220
2022北京冬奥会纪念版徽章
日期:2015-08-10 16:30:32操作系统版块每日发帖之星
日期:2016-05-10 19:22:58操作系统版块每日发帖之星
日期:2016-05-10 19:22:58操作系统版块每日发帖之星
日期:2016-02-18 06:20:00操作系统版块每日发帖之星
日期:2016-03-01 06:20:00操作系统版块每日发帖之星
日期:2016-03-02 06:20:0015-16赛季CBA联赛之上海
日期:2019-09-20 12:29:3219周年集字徽章-周
日期:2019-10-01 20:47:4815-16赛季CBA联赛之八一
日期:2020-10-23 18:30:53操作系统版块每日发帖之星
日期:2016-05-10 19:22:58月度论坛发贴之星
日期:2016-01-31 22:25:02操作系统版块每日发帖之星
日期:2016-05-10 19:22:58
发表于 2014-12-17 15:17 |显示全部楼层
虽然不做深入的异步编程设计,但是浪费内存这是必须的呀
总要有空间来保留执行状态,这样才能程序上路高速运行;

如果想省内存来回就要更多一次申请释放资源的开销了——现在内存不值钱,别小气

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
发表于 2014-12-17 15:18 |显示全部楼层
回复 3# yulihua49

对于你的做法我有点疑惑:
如果由于调用SendNet而导致该thread的context被切换,这个thread就闲下来了对吧,你当然不希望这个thread闲着对不对,但此时你需要怎么把别的任务调度到这个thread上呢?

论坛徽章:
220
2022北京冬奥会纪念版徽章
日期:2015-08-10 16:30:32操作系统版块每日发帖之星
日期:2016-05-10 19:22:58操作系统版块每日发帖之星
日期:2016-05-10 19:22:58操作系统版块每日发帖之星
日期:2016-02-18 06:20:00操作系统版块每日发帖之星
日期:2016-03-01 06:20:00操作系统版块每日发帖之星
日期:2016-03-02 06:20:0015-16赛季CBA联赛之上海
日期:2019-09-20 12:29:3219周年集字徽章-周
日期:2019-10-01 20:47:4815-16赛季CBA联赛之八一
日期:2020-10-23 18:30:53操作系统版块每日发帖之星
日期:2016-05-10 19:22:58月度论坛发贴之星
日期:2016-01-31 22:25:02操作系统版块每日发帖之星
日期:2016-05-10 19:22:58
发表于 2014-12-17 15:18 |显示全部楼层
codechurch 发表于 2014-12-17 14:57
回复 4# yulihua49


你好,这些接口都是自己手动包装实现的吗???

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
发表于 2014-12-17 15:27 |显示全部楼层
本帖最后由 yulihua49 于 2014-12-17 15:29 编辑
windoze 发表于 2014-12-17 15:18
回复 3# yulihua49

对于你的做法我有点疑惑:

这个线程不会闲下来,它回到调度器的顶部(原帖,60楼,15行),并继续epoll_wait.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP