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

按引用传值是否线程安全?如何基于C++标准验证无数据竞争?

关于C++线程代码的数据竞争与引用传递线程安全的解答

代码示例

#include <thread>

void foo(int& value)
{
  // do nothing
}

int main()
{
  int value = 42;

  std::thread t1([&value]{ foo(value); });
  std::thread t2([&value]{ value = 100500; });

  t1.join();
  t2.join();

  return 0;
}

问题1:如何基于C++标准或cppreference验证此处不存在数据竞争?

根据C++标准(N4950)对数据竞争的定义:当两个执行线程访问同一内存位置,且至少一个访问是修改操作,同时这些访问没有被同步操作(如join、互斥锁等)排序时,才会发生数据竞争。

结合代码分析:

  • 线程t1捕获value的引用并调用foo(value),但foo内部未对value执行任何读、写操作。引用绑定(包括lambda捕获、函数参数传递)仅建立对象别名,不构成对对象内存的访问,因此t1线程中不存在对value内存位置的有效访问。
  • 仅线程t2对value执行写操作,没有其他线程同时访问该内存位置。

由于数据竞争的核心前提(两个线程对同一内存位置的访问,且至少一个是写)不成立,因此这段代码不存在数据竞争。

问题2:按引用传递属于线程安全操作吗?

首先纠正表述:此处实际是按引用传递函数参数,并非“传值”。

引用传递本身只是单个线程内完成的绑定操作(比如主线程创建线程时完成lambda的引用捕获,或调用foo时完成参数绑定),这个绑定过程本身不存在多线程安全问题,但引用传递不保证线程安全:

  • 线程安全的核心是对共享对象的访问逻辑:如果多个线程通过引用访问同一共享对象,且至少一个线程执行写操作,同时未通过同步机制(如join、互斥、原子操作等)约束访问顺序,就会触发数据竞争,导致未定义行为。
  • 若仅单个线程通过引用访问对象,或所有访问都通过同步操作排序,则不会有安全问题。

简言之:引用传递只是一种参数传递方式,本身不提供线程安全保障,线程安全需要依赖对共享对象访问的同步控制。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 19:15:02