任何一个线程只要创建并运行了EventLoop都是IO线程IO线程不一定是主线程(IO,逻辑运算)EventLoopThread创建了一个线程在线程函数中创建一个EventLoop::loop开启事件轮询
#include
继承自 noncopyable .
[图例]
EventLoopThread::EventLoopThread(const ThreadInitCallback &cb) : loop_(NULL), exiting_(false), thread_(boost::bind(&EventLoopThread::threadFunc, this)), mutex_(), cond_(mutex_), callback_(cb) { } // threadFunc 绑定一个线程处理函数 当启动线程时,会创建一个loop对象 void EventLoopThread::threadFunc() { EventLoop loop; if (callback_) // 如果注册了回调函数 { callback_(&loop); // 执行回调函数 } { MutexLockGuard lock(mutex_); loop_ = &loop; cond_.notify(); } loop.loop(); // 开启事件轮询 // 如果结束了事件轮询,就会退出这个线程,所以loop_指向了栈对象也没关系 }3 析构函数
EventLoopThread::~EventLoopThread() { exiting_ = true; loop_->quit(); thread_.join(); // pthread_join回收线程 } void EventLoop::quit() { quit_ = true; if (!isInLoopThread()) // 如果是io线程 eventfd唤醒通知其他线程 { wakeup(); } }4 启动线程
EventLoop *EventLoopThread::startLoop() { assert(!thread_.started()); // 断言该线程没有被启动 thread_.start(); // 启动线程,回调之前的threadFunc 会开启loop轮询 { MutexLockGuard lock(mutex_); while (loop_ == NULL) { cond_.wait(); // 条件变量的等待,必须要等启动的io子线程通知父线程已经初始化完毕 } } return loop_; }5 测试用例
#include#include #include #include using namespace muduo; using namespace muduo::net; void runInThread() { printf("runInThread(): pid = %d, tid = %d ---------------------------启动io线程n", getpid(), CurrentThread::tid()); } void startEventLoop() { printf("start EventLoop ==============================启动n"); } void runThread(int a) { printf("aaaaaaaaaa =========== %dn",a); } int main() { printf("main(): pid = %d, tid = %dn", getpid(), CurrentThread::tid()); auto f1 = std::bind(startEventLoop); EventLoopThread loopThread(f1); EventLoop *loop = loopThread.startLoop(); // 异步调用runInThread,即将runInThread添加到loop对象所在IO线程,让该IO线程执行 loop->runInLoop(runInThread); sleep(1); // runAfter内部也调用了runInLoop,所以这里也是异步调用 loop->runAfter(1,std::bind(runThread,1)); loop->runAfter(2, runInThread); loop->runAfter(1,std::bind(runThread,1)); // 连续添加3个定时器,会刷新第一次,和第三次的定时器得最早到期时间 sleep(3); loop->quit(); printf("exit main().n"); }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)