无法修改其他线程中 ref 传递的值

Posted

技术标签:

【中文标题】无法修改其他线程中 ref 传递的值【英文标题】:Can't modify value passed by ref in other thread 【发布时间】:2018-07-03 12:18:43 【问题描述】:

我试图向一位同事演示为什么您最好将 const 引用传递给使用以下代码执行只读操作的函数。令我惊讶的是,它会打印“它很安全!”,即使我在另一个线程正在休眠时更改了 passedBool 的值。

我试图找出我是否在某处打错字,编译器是否优化了代码并通过复制传递passedBool 以避免一些开销,或者是否启动另一个线程会创建passedBool 的本地副本。

class myClass

public:
  myClass(bool& iBool)
  
    t = thread(&myClass::myMethod,this,iBool);
  

  ~myClass()
  
    t.join();
  

private:
  thread t;

  void myMethod(bool& iBool)
  
    this_thread::sleep_for(chrono::seconds(1));

    if(iBool)
      cout << "It's safe!" << endl;
    else
      cout << "It's NOT safe!!!" << endl;
  
;


void main()

  bool passedBool = true;

  cout << "Passing true" << endl;
  myClass mmyClass(passedBool);  

  cout << "Changing value for false" <<endl;
  passedBool = false;

  cout << "Expect \"It's NOT safe!!!\"" <<endl;

【问题讨论】:

【参考方案1】:

线程函数的参数按值移动或复制。如果 需要将引用参数传递给线程函数,它有 被包装(例如使用 std::ref 或 std::cref)。

from here

【讨论】:

这很有趣...当使用 std::cref() 包装器更改线程初始化并更改 const bool&amp; passedBool 的参数类型时,我达到了“不安全”状态,就好像最初的 passBool 是从不强制转换为 const 我认为,这里的const修饰符是为了防止子线程程序修改值。这就像调用 func(const bool& val)。 func 不能修改 val,但是 caller 可以。

以上是关于无法修改其他线程中 ref 传递的值的主要内容,如果未能解决你的问题,请参考以下文章

Java String引用传递问题

C#同样是引用,ref和out到底有什么区别?

无法通过引用 C++ 传递值

C#:关键字out和ref之间的区别

juc线程高级特性

关于组件间传递ref对象的思考