- 论坛徽章:
- 15
|
本帖最后由 yulihua49 于 2015-03-02 16:02 编辑
windoze 发表于 2015-01-20 17:56
回复 8# yulihua49
嗯,所以说光做coroutine+Async I/O是不够的,你总归要想办法和foreign thread通信, ...
这个AIO file 与协程结合的方案行吗?节后开发服务器都关了,暂时没办法测试。
通过eventfd,结合libaio和epoll。那个do_event是SDBC框架封装好的,与epoll调度器的协程接口。- #include <stdio.h>
- #include <libaio.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <libaio.h>
- #include <sys/eventfd.h>
- #include <scsrv.h> //这个是SDBC特定的
- static int AIO_oper(int fd,char *buff,size_t iosize,int flg)
- {
- io_context_t myctx;
- int rc,num;
- uint64_t finished_aio;
- struct iocb iocb,*io=&iocb;
- struct io_event event;
- int efd = eventfd(0, 0);
- if (efd == -1) {
- return flg?write(fd,buff,iosize):read(fd,buff,iosize);
- }
- io_set_eventfd(io,efd);
- io_queue_init(1, &myctx);
- if(flg) io_prep_pread(io, fd, buff, iosize, 0);
- else io_prep_pwrite(io, fd, buff, iosize, 0);
- rc = io_submit(myctx, 1, &io);
- if(rc<0) {
- close(efd);
- io_destroy(myctx);
- return flg?write(fd,buff,iosize):read(fd,buff,iosize);
- }
- rc = do_event(efd,0,0);//yield to epoll
- if(rc==0) read(efd, &finished_aio, sizeof(finished_aio));
- close(efd);
- num = io_getevents(myctx, 1, 1, &event, NULL);
- if(num>0) {
- if(event.res2==0) num=event.res;
- else num=-1;
- }
- io_destroy(myctx);
- return num;
- }
- int AIO_read(int fd,char *buff,size_t iosize)
- {
- return AIO_oper(fd,buff,iosize,0);
- }
- int AIO_write(int fd,char *buff,size_t iosize)
- {
- return AIO_oper(fd,buff,iosize,1);
- }
复制代码 调用AIO_read或AIO_wrote就像read或write一样。所不同的就是中间可能yield过。
之前和之后可能不是同一个线程。
在SDBC交易中间件框架里采用AIO——file,倒不是性能如何如何,而在于在等待IO期间,线程yield去为别的客户服务了。
改善用户体验。
|
|