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

栈上竞态条件(Race Condition):如何用互斥锁避免栈对象成员变量竞争?

解决栈对象版本Hello类的竞态条件问题

嘿,这个问题很典型!咱们先拆解一下:你的栈对象版本里,多个线程同时访问并修改Hello类的成员变量_i,没有任何同步机制,这就导致了竞态条件——多个线程的读写操作互相干扰,最终_i的值会出现不可预期的错误。

要解决这个问题,咱们只需要给访问_i的临界区加互斥锁就行,具体步骤如下:

1. 给Hello类添加互斥锁成员

把std::mutex作为Hello类的私有成员,这样每个Hello对象都有自己独立的锁,不会和其他对象的锁冲突,保证锁的粒度合理。

2. 在成员函数中使用锁保护临界区

在say_hello函数里,用std::lock_guard<std::mutex>(或者std::unique_lock)来包裹所有访问和修改_i的代码。std::lock_guard会在构造时自动加锁,析构时自动解锁,避免手动解锁的遗漏。

修改后的完整代码

#include <thread>
#include <iostream>
#include <vector>
#include <mutex>

class Hello {
    int _i;
    std::mutex _mu; // 给每个Hello对象分配独立的互斥锁
public:
    Hello() : _i(0) {} // 初始化_i为0

    void say_hello() {
        // 使用lock_guard自动管理锁的生命周期
        std::lock_guard<std::mutex> lock(_mu);
        _i++; // 临界区:修改_i
        std::cout << "Hello from thread! _i = " << _i << std::endl; // 临界区:读取_i
    }
};

void hellos_in_stack() {
    Hello h; // 栈对象
    std::vector<std::thread> threads;

    for (int i = 0; i < 5; ++i) {
        threads.emplace_back(&Hello::say_hello, &h); // 多个线程调用同一个栈对象的成员函数
    }

    for (auto& t : threads) {
        t.join();
    }
}

void hellos_in_heap() {
    Hello* h = new Hello(); // 堆对象
    std::vector<std::thread> threads;

    for (int i = 0; i < 5; ++i) {
        threads.emplace_back(&Hello::say_hello, h);
    }

    for (auto& t : threads) {
        t.join();
    }
    delete h;
}

int main() {
    std::cout << "Testing stack object version:\n";
    hellos_in_stack();

    std::cout << "\nTesting heap object version:\n";
    hellos_in_heap();

    return 0;
}

关键说明

  • 锁的封装:把_mu作为类的成员,确保只有Hello类的成员函数能访问这个锁,符合封装原则,也避免了全局锁带来的不必要的竞争。
  • 自动锁管理:std::lock_guard是RAII风格的锁管理工具,即使say_hello函数中途抛出异常,它也会在析构时自动解锁,不会导致死锁。
  • 临界区范围:尽量把锁的范围缩小到必要的代码块(也就是真正访问共享变量_i的部分),这样能减少锁的持有时间,提升并发效率。

这样修改后,不管是栈对象还是堆对象版本,_i的读写操作都会被互斥锁保护,不会再出现竞态条件啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:03:49