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

多线程下加pthread互斥锁仍重复写入文件的问题排查

问题分析与解决方案

让我们一步步拆解你的问题,找出锁失效的核心原因:

1. 互斥锁未正确初始化(最可能的元凶)

pthread_mutex_t 类型的锁必须经过初始化才能正常工作,未初始化的锁行为是未定义的——看起来加了锁,但实际上根本没起到互斥作用。你需要确认锁的初始化方式:

  • 如果是类的静态成员,用静态初始化:
    pthread_mutex_t Client::lock = PTHREAD_MUTEX_INITIALIZER;
    
  • 如果是实例成员,要在构造函数中手动初始化,析构函数中销毁:
    Client::Client() {
        pthread_mutex_init(&lock, NULL);
    }
    
    Client::~Client() {
        pthread_mutex_destroy(&lock);
    }
    

2. 锁的作用域不匹配

如果你的多个 Client 实例共享同一个 FILE* fp,但每个实例持有自己的 lock,那不同实例的线程依然会同时写入文件——因为它们用的不是同一把锁。这种情况下,锁应该是全局变量,或者设为 Client 类的静态成员,确保所有操作该文件的线程都共用同一把锁。

3. 代码中的变量错误(虽不直接导致写入混乱,但会引发数据异常)

你的代码里有明显的变量定义和使用错误:

// 先定义了double类型的q90
double q90, q95, q99 = 0.0;
// 又重新定义了int类型的q90,覆盖了之前的变量
int q90 = (int)ceil(0.90 * double(RPS));
// 后面又用了未定义的Index90,明显是笔误
q90 = serviceTime.at(Index90-1)/1e6;

修正后的代码应该是:

std::sort(serviceTime.begin(), serviceTime.end());
int idx90 = (int)ceil(0.90 * double(RPS));
int idx95 = (int)ceil(0.95 * double(RPS));
int idx99 = (int)ceil(0.99 * double(RPS));
// 用正确的索引变量读取排序后的数据
double q90 = serviceTime.at(idx90 - 1)/1e6;
double q95 = serviceTime.at(idx95 - 1)/1e6;
double q99 = serviceTime.at(idx99 - 1)/1e6;

4. 额外建议:用RAII避免手动解锁失误

手动调用 pthread_mutex_lock/unlock 容易因为代码分支、异常等情况遗漏解锁,建议改用C标准库的RAII锁(C11及以上支持),更安全可靠:

#include <mutex>

// 替换pthread_mutex为std::mutex
std::mutex Client::lock;

void Client::response(Sender* send, FILE *fp){
    // 自动加锁,离开作用域自动解锁
    std::lock_guard<std::mutex> guard(lock);
    if (status == ROI) {
        if (condition) {
            RPS = serviceTime.size();
            std::sort(serviceTime.begin(), serviceTime.end());
            int idx90 = (int)ceil(0.90 * double(RPS));
            int idx95 = (int)ceil(0.95 * double(RPS));
            int idx99 = (int)ceil(0.99 * double(RPS));
            double q90 = serviceTime.at(idx90-1)/1e6;
            double q95 = serviceTime.at(idx95-1)/1e6;
            double q99 = serviceTime.at(idx99-1)/1e6;
            fprintf(fp, "%d, %.3f, %.3f, %.3f\n", RPS, q90, q95, q99);
            fflush(fp);
            serviceTime.clear();
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:51:45