我正在阅读“C ++ Concurrency in Action”。 我对下面的代码片段有疑问。
struct func
{
int& i;
func(int& i_):i(i_){}
void operator()()
{
for(unsigned j=0;j<1000000;++j)
{
do_something(i); //Can have issue of dangling references
}
}
};
void oops()
{
int some_local_state=0;
func my_func(some_local_state);
std::thread my_thread(my_func);
my_thread.detach();
}
作者说,为了避免这种情况,一种方法是 使线程功能自包含并将数据复制到线程而不是共享数据
我明白这个问题是因为创建的函数对象是oop函数的本地函数,当oops函数完成时,对象超出了范围,但是我无法理解如何避免作者提到它的方式。
答案 0 :(得分:4)
问题不在于func
对象。 std::thread
会复制您的仿函数。
首先,构造函数复制/移动所有参数(都是函数 对象f和所有args ...)到线程可访问的存储
问题是您的仿函数保留int& i;
的参考some_local_state
,some_local_state
在some_local_state
超出范围时确实无效。
要解决此问题,请复制std::shared_ptr
的值,而不是保留对它的引用。如果您需要共享访问权限,请考虑使用display: table;
。