You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何timerfd结合epoll无法按预期工作?负载生成器计时异常

问题分析与解决

核心原因

timerfd的工作机制是:每次超时后,内核会向文件描述符写入一个64位无符号整数(记录超时次数),如果不读取这个值,内核会持续将该fd标记为可读状态,导致epoll_wait反复触发。你的代码在处理timer_fd事件时,完全没有读取这个计数器值,这就是epoll_wait在一个5秒周期内被触发上千次的直接原因。

修复代码

修改calculate_throughput函数中处理timer_fd的逻辑,添加读取计数器的操作:

if (events[i].data.fd == timer_fd) {
    // 必须读取timerfd的计数器值,否则内核会持续触发EPOLLIN事件
    uint64_t expirations;
    ssize_t ret = read(timer_fd, &expirations, sizeof(expirations));
    if (ret != sizeof(expirations)) {
        perror("read timerfd");
        exit(1);
    }

    gettimeofday(&end, NULL);
    float wait_time_s = time_diff(&end, &start);
    float throughput = (float)total_requests / wait_time_s;

    printf("Throughput (requests/second): %f\n", throughput);

    gettimeofday(&start, NULL);
    total_requests = 0; // 重置请求计数,保证下一次计算的是新周期内的请求量
}

另外需要补充请求计数的线程安全更新逻辑:

  1. 添加全局变量与互斥锁:
// 全局区域添加
int total_requests = 0;
pthread_mutex_t reqCountMutex = PTHREAD_MUTEX_INITIALIZER;
  1. 在user_function中请求成功的位置(info->total_count++处)更新全局计数:
else{
  info->total_count++;
  // 线程安全更新全局请求计数
  pthread_mutex_lock(&reqCountMutex);
  total_requests++;
  pthread_mutex_unlock(&reqCountMutex);
}

额外优化提示

  • 全局变量x的读写未加同步,多线程环境下存在竞态,调试完成后建议移除或添加互斥锁保护。
  • calculate_throughput函数中的total_requests初始值为0,但原代码没有任何地方递增它,必须通过上述线程安全的方式更新才能得到正确的吞吐量数据。

内容的提问来源于stack exchange,提问作者Sourav Paul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 09:03:14