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

在以下C++多线程示例中是否需要同步机制?

关于shared_ptr线程安全的误解纠正

先看cppreference的这段描述:

所有成员函数(包括拷贝构造函数和拷贝赋值运算符)都可以由多个线程在不同的shared_ptr实例上调用,无需额外同步,即使这些实例是副本且共享同一对象的所有权。

你对这段描述的理解错在了范围——它只保证shared_ptr自身的操作是线程安全的,和它指向的对象无关。

核心区别

  • shared_ptr自身的线程安全:多个线程对不同的shared_ptr实例(共享同一对象所有权)执行拷贝、赋值、调用use_count()/reset()等成员函数时,不需要额外同步,因为它内部的引用计数操作是原子实现的,不会出现竞态问题。
  • 指向对象的线程安全:shared_ptr不会给它指向的对象自动添加同步机制。当多个线程通过不同的shared_ptr实例访问、修改该对象的成员时,必须自己处理同步,否则会出现竞态条件,导致数据错误或输出混乱。

你的代码问题分析

你提供的代码中,三个线程通过不同的shared_ptr实例调用fun1/fun2/fun3,这些函数都在修改Demo::Value,并且直接向cout输出(cout无同步的多线程访问也会导致输出混乱)。这属于典型的无同步共享数据修改,必然出现随机的输出和错误的Value计算结果。

修正后的代码示例

给共享资源加上互斥锁,保证同一时间只有一个线程能修改Value和输出:

#include <iostream>
#include <memory>
#include <thread>
#include <mutex>
using namespace std;

class Demo
{
public:
    int Value;
    std::mutex mtx; // 互斥锁,保护共享资源
    Demo():Value(10){}

    void fun1()
    {
        for(int i=0; i<300000; i++)
        {
            std::lock_guard<std::mutex> lock(mtx); // 自动加锁/解锁,避免死锁
            Value = Value + i;
            std::cout << "Value1 :" << Value << std::endl;
        }
    }
    void fun2()
    {
        for(int i=0; i<300000; i++)
        {
            std::lock_guard<std::mutex> lock(mtx);
            Value = Value + i;
            std::cout << "Value2 :" << Value << std::endl;
        }
    }
    void fun3()
    {
        for(int i=0; i<300000; i++)
        {
            std::lock_guard<std::mutex> lock(mtx);
            Value = Value + i;
            std::cout << "Value3 :" << Value << std::endl;
        }
    }
};

int main()
{
    std::shared_ptr<Demo> ptr1(new Demo);
    std::thread t1(&Demo::fun1, ptr1);

    std::shared_ptr<Demo> ptr2(ptr1);
    std::thread t2(&Demo::fun2, ptr2);

    std::shared_ptr<Demo> ptr3(ptr2);
    std::thread t3(&Demo::fun3, ptr3);

    t1.join();
    t2.join();
    t3.join();
}

修正后,每个线程进入修改Value和输出的临界区时会独占锁,避免了竞态条件,输出会有序,Value的计算结果也会正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 16:13:36