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

C++线程编程:循环尝试获取互斥锁的代码是否有效?

关于C++ shared_mutex加锁逻辑的规范写法

嘿,作为C++线程编程新手,你能想到用shared_mutex来区分OpenGL库的读写场景(绘图读VAO、增删写VAO),这点思路非常对——读写锁本来就是为这类读多写少的并发场景设计的,能大幅提升并发效率。不过你的这段代码确实存在冗余和可优化的地方,咱们来仔细拆解:

先说说你现有代码的问题

unique_lock<shared_mutex> lock(someSharedMutex);
if (!lock.owns_lock()) {
    while (!lock.try_lock()) {}
}
// 修改数据

这里最关键的误解是:unique_lock<shared_mutex> lock(someSharedMutex); 这个构造函数默认会调用lock()方法,也就是阻塞当前线程直到成功获取排他锁。所以lock.owns_lock()在这里几乎永远是true,后面的if判断和自旋循环完全是多余的,根本不会被执行。你觉得代码能正常运行,其实是因为构造函数已经帮你完成了加锁的核心工作。

退一步说,假设你本来想构造一个不自动加锁的unique_lock(比如用defer_lock参数),那while (!lock.try_lock()) {}这种自旋等待的方式也不推荐——它会让线程一直占用CPU空转,在高并发场景下会严重浪费系统资源,远不如让操作系统把线程挂起,直到锁可用时再唤醒(也就是lock()的默认行为)高效。

适合你场景的规范写法

结合你的OpenGL库需求:绘图线程用共享锁(允许多个读线程同时访问VAO列表),VAO增删操作用排他锁(同一时间只能有一个写线程修改列表),正确的代码应该是这样的:

写操作(VAO添加/移除)

void addVAO(const VAO& new_vao) {
    // 构造unique_lock时自动获取排他锁,阻塞直到拿到锁
    unique_lock<shared_mutex> lock(someSharedMutex);
    // 安全修改VAO存储vector
    vao_storage.push_back(new_vao);
}

void removeVAO(size_t index) {
    unique_lock<shared_mutex> lock(someSharedMutex);
    if (index < vao_storage.size()) {
        vao_storage.erase(vao_storage.begin() + index);
    }
}

读操作(绘图)

void drawAllVAOs() {
    // 用shared_lock获取共享锁,多个读线程可同时持有
    shared_lock<shared_mutex> lock(someSharedMutex);
    for (const auto& vao : vao_storage) {
        vao.draw();
    }
}

特殊场景的非阻塞加锁(如果需要)

如果你确实有需求不想让线程阻塞(比如要在等待锁的间隙做其他操作),可以用defer_lock参数构造unique_lock,然后配合try_lock()或者带超时的try_for()/try_until(),但绝对不要用自旋循环:

bool tryAddVAO(const VAO& new_vao) {
    unique_lock<shared_mutex> lock(someSharedMutex, defer_lock);
    if (lock.try_lock()) {
        vao_storage.push_back(new_vao);
        return true;
    }
    // 没拿到锁,返回失败或者做其他处理
    return false;
}

总结

你的代码虽然能运行,但存在冗余逻辑和潜在的效率问题。直接用unique_lock的默认构造(自动加排他锁)是最规范、高效的方式,完全适配你VAO增删的写操作场景;而绘图读操作则用shared_lock获取共享锁,最大化并发能力。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:54:15