acl
acl copied to clipboard
socket与fiber是如何结合的?
大神新好!
看了acl的源码,对协程的流程基本了解,不太明白的是socket与fiber是如何联接起来的。
像下面的示例代码,fiber_echo这个类是继承了acl::fiber因此可以在fiber->start()的时候运行run()虚函数,但是当conn_->read() 的时候,涉及到socket的读写,如何导致与此fiber暂停,然后在read成功后再继续运行,底层是如何实现的? 有没有相关的文档介绍?
acl::fiber* fb = new fiber_echo(conn);
fb->start();
// 客户端协程处理类,用来回显客户发送的内容,每一个客户端连接绑定一个独立的协程
class fiber_echo : public acl::fiber
{
public:
fiber_echo(acl::socket_stream* conn) : conn_(conn) {}
private:
acl::socket_stream* conn_;
~fiber_echo(void) { delete conn_; }
// @override
void run(void) {
char buf[8192];
while (true) {
int ret = conn_->read(buf, sizeof(buf), false);
if (ret == -1) {
break;
}
if (conn_->write(buf, ret) != ret) {
break;
}
}
delete this; // 自销毁动态创建的协程对象
}
};
acl 协程hook了底层的I/O API,所以可以将 socket 的 I/O 过程协程,我曾在 https://mp.weixin.qq.com/s/XAEzZAUYuOhuqMOszNFe2A 文章中介绍过 acl 协程的原理,但还未曾讲过 acl 协程是如何 hook 系统 I/O API 的,将来有时间可以讲讲这块。
大概是这张图所描述的内容吧。doc/articles/acl_fiber.pptx中的图。 协程运行到conn_->read()的时候,通过hookapi,实现注册读事件,挂接到epoll引擎上, 读事件到来后,此协程再转为运行态。

对,原理是这样的。