muduo源码分析之EventLoop::runInLoop()函数

本文深入探讨了muduo库中EventLoop::runInLoop()函数的实现,讲解了如何利用eventfd唤醒线程以及在EventLoop中执行用户回调。文中通过示例详细阐述了线程间通信和EventLoop对象在多线程环境中的使用,包括EventLoopThread的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前面所学的一些内容,从最早的什么都不做的EventLoop开始,到后面的定时器,功能不断在丰富,不过一直都是单线程下的。也就是说EventLoop对象在主线程中进行事件循环。今天花了一天时间所学习的EventLoop::runInLoop()就打开muduo多线程编程的大门。

1.eventfd唤醒线程

先来看看这个eventfd的用法,直接上示例:

#include <stdio.h>  
#include <unistd.h>  
#include <sys/time.h>  
#include <stdint.h>  
#include <pthread.h>  
#include <sys/eventfd.h>  
#include <sys/epoll.h>  

int efd = -1;  

void *read_thread(void *dummy)  
{  
    int ret = 0;  
    uint64_t count = 0;  
    int ep_fd = -1;  
    struct epoll_event events[10];  

    if (efd < 0)  
    {  
        printf("efd not inited.\n");  
        goto fail;  
    }  

    ep_fd = epoll_create(1024);  
    if (ep_fd < 0)  
    {  
        perror("epoll_create fail: ");  
        goto fail;  
    }  

    {  
        struct epoll_event read_event;  

        read_event.events = EPOLLHUP | EPOLLERR | EPOLLIN;  
        read_event.data.fd = efd;  

        ret = epoll_ctl(ep_fd, EPOLL_CTL_ADD, efd, &read_event);  
        if (ret < 0)  
        {  
            perror("epoll ctl failed:");  
            goto fail;  
        }  
    }  

    while (1)  
    {  
        ret = epoll_wait(ep_fd, &events[0], 10, 5000);  
        if (ret > 0)  
        {  
            int i = 0;  
            for (; i < ret; i++)  
            {  
                if
### 编译时出现`undefined reference to muduo::net::EventLoop::~EventLoop()`的原因分析 当遇到此类链接错误时,通常是因为链接器无法找到特定符号的定义。对于`muduo::net::EventLoop::~EventLoop()`这类错误,可能原因有多个方面: - **库文件缺失或不匹配**:如果使用的静态库(`.a`)版本与源码期望的不同,则可能导致某些成员函数未能正确编译进入最终二进制文件中[^2]。 - **ABI兼容性问题**:使用不同GCC版本编译可能会引入ABI(应用程序二进制接口)差异,特别是启用C++11特性之后。这可以通过设置预处理器宏来缓解,即添加`-D_GLIBCXX_USE_CXX11_ABI=0`作为编译选项之一[^3]。 - **链接顺序不当**:在命令行指定依赖关系时,应确保先列出目标对象(.o),再跟随其所需的所有外部库;否则即使存在相应实现也可能因解析时机不对而被认为“未定义”。此外,在多库场景下,还需注意各库间的相互依存次序[^4]。 针对上述情况的具体解决方案可以考虑以下几个方向: #### 修改Makefile或CMakeLists.txt配置 为了使项目能够顺利构建并运行,建议按照以下方式调整构建脚本中的相关内容: ```makefile # Makefile 示例 g++ -std=c++11 -I/path/to/muduo/include \ -L/path/to/muduo/lib \ -Wl,-rpath,/path/to/muduo/lib \ main.o -lmuduo_net_cpp11 -lmuduo_base_cpp11 -lpthread -ldl ``` 或者如果是基于CMake的话, ```cmake # CMakeLists.txt 示例 set(CMAKE_CXX_STANDARD 11) add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) find_library(MUDUO_BASE_LIB NAMES muduo_base_cpp11 PATHS /path/to/muduo/lib NO_DEFAULT_PATH) find_library(MUDUO_NET_LIB NAMES muduo_net_cpp11 PATHS /path/to/muduo/lib NO_DEFAULT_PATH) target_link_libraries(${PROJECT_NAME} PRIVATE ${MUDUO_NET_LIB} ${MUDUO_BASE_LIB}) ``` 以上改动旨在确保采用支持C++11特性的库变体,并且通过适当设定路径让链接过程能找到所需的动态/静态库资源。 #### 验证第三方库的有效性和完整性 考虑到可能存在旧版遗留下来的残留物影响新安装的结果,推荐重新下载最新稳定发行包并依照官方文档说明完成本地部署工作。同时利用工具如`nm`检查所选`.a`档案内是否存在预期条目以确认无误后再继续后续操作。 #### 更新环境变量以便于开发测试阶段临时解决问题 有时出于快速验证目的可暂时修改LD_LIBRARY_PATH等环境变量指向正确的共享库位置,但这不是长久之计,正式发布前仍需完善工程化管理流程确保打包产物的一致性。 ```bash export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值