【问题标题】:passing by reference in C++ 11 threads; changes are localized在 C++ 11 线程中通过引用传递;更改已本地化
【发布时间】:2015-02-15 06:20:43
【问题描述】:

我正在尝试使用 C++ 11 线程加快对 opencv 代码的一些处理。

与此同时,我正在使用矢量来共享数据

请考虑以下代码:

start_t = cv::getTickCount();
std::vector <std::thread>   tMSE_Calc(nComparisons);
std::vector<float> sum;
sum.resize(nComparisons);

for(int i = 0 ; i < nComparisons ; ++i)
{
    tMSE_Calc[i] = std::thread(FindMSE_Fast, vector1, vector2, sum, i);
}

for(int i = 0 ; i < nComparisons ; ++i)
{
    tMSE_Calc[i].join();
}
end_t = cv::getTickCount();
logfile << "Actual Comparison Took " << (end_t - start_t) * freq * 1000 << " milliseconds"<< std::endl;

for(int i = 0 ; i < nComparisons ; ++i)
{
    std::cout << "Sum[" << i << "] = " << sum[i] << std::endl;
}

我有一个线程函数:

void FindMSE_Fast(cv::Mat& m1, cv::Mat& m2, std::vector<float>& sumVec, int idx)
{
    cv::Mat s;
    cv::absdiff(m1, m2, s);
    s = s.mul(s);
    cv::Scalar sum = cv::sum(s);
    sumVec[idx] = cv::sqrt(sum[0]);
    std::cout << "Difference is: " << cv::sqrt(sum[0]) << "index is: " << sumVec[idx] << std::endl;

    //std::cout << "Difference is: " << cv::sqrt(sum[0]) << std::endl;
}

在我看来,向量和应该在线程调用结束时修改,但是当我稍后在主线程中打印它时,它的所有内容都为零。

为了通过引用传递,我们需要对函数参数做些什么不同的事情吗?

【问题讨论】:

  • 这有很多骗局。基本上,std::thread 的构造函数会复制参数,本质上是按值传递。通过引用使用 lambda 捕获或使用 std::ref

标签: c++ multithreading c++11 stdvector stdthread


【解决方案1】:

绑定的函数参数被复制而不是通过引用传递。这种行为是相同的,例如,std::bind()。参数作为推导的T&amp;&amp; 传递给构造函数,但这仅用于初始化一些保存的值。

如果您不想复制参数,则可以传递 std::reference_wrapper&lt;T&gt;,例如,使用

std::thread(FindMSE_Fast, vector1, vector2, std::ref(sum), i)

同时通过引用传递sum。由于std::reference_wrapper&lt;T&gt; 有一个到T&amp; 的转换运算符,您的函数将被适当地调用。

【讨论】:

    猜你喜欢
    • 2023-04-07
    • 2020-05-03
    • 2018-07-11
    • 1970-01-01
    • 2021-11-27
    相关资源
    最近更新 更多