线程间的等待通知
pipe
socketpair
eventfd
条件变量
前三个都有文件描述符,都可以方便的利用I/O复用来管理,而条件变量没有
#include <sys/eventfd.h>
int eventfd(unsigned int initval, int flags);
mduo库的线程唤醒利用的eventfd,eventfd 是一个比 pipe 更高效的线程间事件通知机制,eventfd()创建一个“eventfd对象”,这个对象能被用户空间应用用作一个事件等待/响应机制,靠内核去响应用户空间应用事件。一方面它比 pipe 少用一个 file descripor,节省了资源;另一方面,eventfd 的缓冲区管理也简单得多,全部“buffer” 只有定长8 bytes,不像 pipe 那样可能有不定长的真正 buffer。调用这个函数就会返回一个新的文件描述符
//用于eventfd,用于保存eventfd创建的文件描述符
int wakeupFd_;
// unlike in TimerQueue, which is an internal class,
// we don't expose Channel to client.
//wakeupFd_所对应的通道,该通道将会纳入poller_来管理
boost::scoped_ptr<Channel> wakeupChannel_;//EventLoop只负责wakeupChannel_的生存期,还有其它的channel
//<Functor是回调的任务
std::vector<Functor> pendingFunctors_;
相关的一些重要的函数
//一个线程唤醒另一个线程
void EventLoop::wakeup()
{
uint64_t one = 1;
//往wakeupFd_中写入8个字节就可以唤醒一个等待的线程
ssize_t n = sockets::write(wakeupFd_, &one, sizeof one);
if (n != sizeof one)
{
LOG_ERROR << "EventLoop::wakeup() writes " << n << " bytes instead of 8";
}
}
runInLoop函数是非常重要的一个函数,可以实现异步调用
//在某个线程中执行某个回调函数,该函数可以跨线程使用
void EventLoop::runInLoop(Functor&& cb)
{
// 如果是当前IO线程调用runInLoop,则同步调用cb
if (isInLoopThread())
{
cb();
}
/