2016-12-07 ruki
此版本主要增加stackless协程模块以及为嵌入式平台增加micro微模块编译(~64K)。 此stackless协程模块比之前的stackfull协程实现更加的轻量高效,切换效率提升5、6倍,在macosx上测试1000w次切换仅需40ms 当然易用性和灵活性上,还是stackfull模式更有优势(tbox两种模式都已支持,接口类似)。 stackless协程使用见:stackless协程使用文档 stackfull协程使用见:stackfull协程使用文档 更多协程服务器demo实现,请参考:协程examples 新特性 针对协程上下文切换,支持mips架构 添加__tb_thread_local__关键字宏 添加 继续阅读 »
2016-10-28 ruki
协程现在已经不是个新东西了,很多语言都提供了原生支持,也有很多开源的库也提供了协程支持。 最近为了要给tbox增加协程,特地研究了下各大开源协程库的实现,例如:libtask, libmill, boost, libco, libgo等等。 他们都属于stackfull协程,每个协程有完整的私有堆栈,里面的核心就是上下文切换(context),而stackless的协程,比较出名的有protothreads,这个比较另类,有兴趣的同学可以去看下源码,这里就不多说了。 那么现有协程库,是怎么去实现context切换的呢,目前主要有以下几种方式: 使用ucontext系列接口,例如:libtask 使用setjmp/longjm 继续阅读 »
2015-11-06 Li Shuai
协程是用户态内的,或者准确点说是线程内部的一种上下文切换技术,由于协程切换是在用户态下完成的,所以省去了线程切换时频繁出入内核态的资源开销,可以形成一种很高效的协作式并发技术。 这个简短的视频介绍了一些有关协程、并发之类的东西,很有意义。 Coroutines, event loops, and the history of Python generators 从里面学习到两种很好的协程的调度方式。把代码拿过来分享一下。 Coroutine trampoline 这种方式下的协程调度比较好理解,就是从一个初始状态开始,一条执行线索不断的在多个协程之间切换,就好像多个协程协作完成一项任务。 代码: def co_tramp 继续阅读 »
2016-10-29 ruki
tbox的协程实现,是stackfull模式的,需要指定独立堆栈和协程函数,目前暂时还不能像golang那样实现堆栈的动态增长,之后会对其进行支持。 目前提供下面一些功能特性: 1. 提供yield切换调度支持,这个是必须的哈 2. 提供suspend(挂起)/resume(恢复)协程接口,不同于yield的是,被suspend后,如果不显示调用resume恢复它,是永远不会被调度到的 3. 提供sleep等待接口支持 4. 提供io调度支持,支持socket等io等待(内部使用epoll, poll, kqueue, select, poll等接口调度) 5. 原生支持stream,socket,http等模块的协程支持,可 继续阅读 »
2016-11-07 ruki
tbox内部的所有io操作都是原生支持协程的,可以在线程和协程间任意切换,内置基于轮询的io调度器(epoll, kqueue等,后续还会支持iocp). 我们在socket操作的时候,只需要像平常顺序编程那样操作就可以实现异步并发收发数据。 这里先给个简答的文件服务器的例子,可参考下,代码非常简单: 文件接收服务器 这个文件服务器的功能很简单,就是不停的接收连接,然后开新协程,进行文件传输。 通过协程,从原始socket写起,也只需要不到100行代码,就可以实现一个高并发的文件服务器。 此处用到了tb_socket_sendf直接对文件句柄操作,发送到socket,内部使用sendfile实现,不需要再上层开buffe 继续阅读 »
2016-12-07 ruki
之前介绍过了stackfull的一些服务器使用例子,这里在贴一些使用stackless协程接口实现的server代码。 其实大部分接口,两者都是类似的,仅仅只是前缀的区别:tb_co_xx 和 tb_lo_xx,唯一需要注意的是: * stackless协程尽量不要使用局部变量 * 不要再嵌套的过程里面进行协程挂起等待 文件接收服务器 这个文件服务器的功能很简单,就是不停的接收连接,然后开新协程,进行文件传输。 通过协程,从原始socket写起,也只需要不到100行代码,就可以实现一个高并发的文件服务器。 此处用到了tb_socket_sendf直接对文件句柄操作,发送到socket,内部使用sendfile实现,不 继续阅读 »
2016-10-30 ruki
新特性 支持make进行直接编译(会去自动下载xmake进行构建) 在平台库中,添加切换context上下文接口(参考boost.context实现原理进行重写,并对部分架构进行优化) 新增跨平台协程模块(支持i386, x86_64, arm, arm64),提供更加易用的高性能并发编程模式 新增基于协程的各种服务器开发实例(包括:简单轻量的http服务器,爬虫。。) 新增poller轮询器接口,实现对epoll, poll, kqueue, select的封装,逐步取代老的aiop接口 新增mbedtls ssl库接口支持,目前已支持:openssl, polarssl, mbedtls tbox所有stream, socke 继续阅读 »
2016-12-03 ruki
tbox之前提供的stackfull协程库,虽然切换效率已经非常高了,但是由于每个协程都需要维护一个独立的堆栈, 内存空间利用率不是很高,在并发量非常大的时候,内存使用量会相当大。 之前考虑过采用stacksegment方式进行内存优化,实现动态增涨,但是这样对性能还是有一定的影响,暂时不去考虑了。 最近参考了下boost和protothreads的stackless协程实现,这种方式虽然易用性和灵活性上受到了很多限制,但是对切换效率和内存利用率的提升效果还是非常明显的。。 因此,我在tbox里面也加上了对stackless协程的支持,在切换原语上参考了protothreads的实现,接口封装上参考了boost的设计,使得更加 继续阅读 »
2016-11-13 ruki
在分析了各大开源协程库实现后,最终选择参考boost.context的汇编实现,来写tbox的切换内核。 在这过程中,我对boost各个架构平台下的context切换,都进行了分析和测试。 在macosx i386和mips平台上实现协程切换时,发现boost那套汇编实现是有问题的,如果放到tbox切换demo上运行,会直接挂掉。 在分析这两个架构上,boost.context切换实现问题,这边先贴下tbox上的context切换demo,方便之后的讲解: 继续阅读 »
2017-02-17 Lu Huang
本文将以 kaldi 中 timit 的例程来看整个 run.sh 脚本的执行过程。本文来自于Running the example scripts (40 minutes) 数据准备 请先进入 kaldi\egs\timit\s5\ 这个目录。 运行环境 由于 kaldi 可以在本地运行,也可以在 Oracle GridEngine 上运行,因此,请修改 cmd.sh。 如果你是在本地运行,请输入 export train_cmd="run.pl --max-jobs-run 10" export decode_cmd="run.pl --max-jobs-run 10" export cuda_cmd="run.p 继续阅读 »