依靠与 const& 参数绑定的参数的 const-ness 是线程不安全的秘诀吗?

Is relying on the const-ness of arguments bind to const& parameters a recipe for thread un-safety?

提问人:Enlico 提问时间:1/26/2023 更新时间:1/26/2023 访问量:33

问:

我刚刚看到了这样的代码

/* whatever */ foo(std::string const& s) {
  // stuff
  auto L = s.length();
  int i{/* init based on L */};
  while (i < L) {
    // do other stuff and maybe
    ++i;
  }
}

我建议人们可以避免定义和写作,而不是 和 .L/* init based on s.length() */(i < s.length())/* init based on L */(i < L)

但是谁真正告诉我,这不会因为与参数对应的参数被另一个并发线程更改而不可预测地改变?s.length()s

C++ 参数 线程安全 const-reference 传递

评论

1赞 StoryTeller - Unslander Monica 1/26/2023
您不需要线程。如果间接调用一个函数,该函数修改了所引用的任何内容,该怎么办?//do other stuffs
0赞 Enlico 1/26/2023
好吧,但在某种程度上我知道我的功能,所以至少我可以验证我没有这样做。而线程是否修改是我无法控制的。s
1赞 Pepijn Kramer 1/26/2023
螺纹不安全有多种。关于此函数的引用是常量的,但在代码中的其他地方可能不是这样(例如,其他线程可能仍具有可修改的访问权限)。因此,在这种情况下,读取仍然需要由互斥锁保护。然后是生命周期方面,如果设计不当,引用引用的对象可能会在您想要使用它时被删除。所以没有常量不能保证任何事情。
0赞 StoryTeller - Unslander Monica 1/26/2023
你知道你的功能吗?以及它从每个库调用的所有其他函数?通过每个潜在的 CB 和用例?令人 印象 深刻。
0赞 Pepijn Kramer 1/26/2023
@Enlico 不,这是错误的思维方式。您不能仅使用本地视图来查看线程问题。线程必须设计到项目中,您需要能够预先指定哪些代码必须是线程安全的,以及对象的生存期有多长。例如,对象的生存期必须比使用它们的线程长,或者线程必须能够延长对象的生存期(例如共享所有权/std::shared_ptr)。

答:

3赞 Sam Varshavchik 1/26/2023 #1

不,没人能告诉你。这是对对象含义的常见误解。const

对象不是承诺其他执行线程不能修改对象,而你却在做你的业务。const

对象是一个承诺,即访问该对象的代码不能修改它(无论“修改”对相关对象意味着什么)。constconst

事实上,根本不需要涉及其他执行线程。这个函数,在“东西”部分,可以调用一些其他函数,这些函数可以通过某处的某个指针或引用访问完全相同的对象,并完全改变它,然后返回到这个函数。fooconstfoo