通过引用向量传递的线程函数启动缓慢

Posted

技术标签:

【中文标题】通过引用向量传递的线程函数启动缓慢【英文标题】:Thread function with passed by reference vector is slow to start 【发布时间】:2011-11-28 11:46:31 【问题描述】:

我一直在查看 C++0x 线程并拥有以下代码:

#include <vector>
#include <iostream>
#include <thread>
void TestFunc(const vector<int>& vVec)

    cout << "in"<<endl;


int main()


    int sizer = 400000000;

    vector<int> vTest(sizer);
    for(int f=0; f<sizer; f++)
        vTest[f] = f;


   cout << "V created." << endl;

   thread one(TestFunc, vTest);

     one.join();    


如您所见,它只是将向量传递给线程。 我不明白的是,出现“V created”消息后有一个暂停。最初这个(我假设)是被复制以在函数中使用的向量。 为了阻止这种情况,我改为通过引用传递,但这没有任何区别。

延迟似乎与向量的大小成正比,这表明它仍在复制(或对数组做某事)。 如果我在没有线程的情况下尝试相同的实验并直接调用函数,则在按值传递时会出现延迟,但在按预期传递时不会出现延迟。

我尝试使用 Boost 线程而不是 C++0x 进行相同的操作(尽管我已经读过它们大致相同)并得到了相同的结果。

这种行为是有原因的,还是我错过了一些非常明显的东西? 谢谢。

抱歉,发布了错误的测试代码。已更正。 编辑:按要求添加包括。

编译: g++44 -std=c++0x -lpthread tester.cpp -o test ...因为我在不支持 C++11 的 Linux (CentOS) 附带的标准 GNU 编译器旁边安装了 GNU 4.4。

【问题讨论】:

TestFunc 最昂贵的部分是跟踪,而不是传递的参数。看来C++0x不支持创建线程 @Mahesh:在什么系统上?这只有 4 亿个,可以轻松放入 32 位 int 中。 @BruceAdi:在 C++11 中,线程是由标准规定的,至少 gcc-4.6 确实支持它们,而且它们可以工作——我每天都在使用它们。 @BruceAdi:如果您使用的是g++,您是否使用-pthread 选项进行编译? 而且,在这种情况下,使用endl 是完全正确的做法。 :-) 【参考方案1】:

我只是推测,因为您尚未发布使用线程的代码版本,但我怀疑您的问题是,默认情况下,std::bind(或boost::bind)会复制所有你绑定的参数。为避免这种情况,您可以使用std::refstd::cref

为了具体说明,您可能会像这样使用bind

std::bind(TestFunc, vTest)

相反,您应该像这样使用它:

std::bind(TestFunc, std::cref(vTest));

【讨论】:

这对我来说似乎有点笨拙。 bind 是否无法判断该函数需要引用并存储引用? +1 我刚刚用你的代码测试了它,你是对的。当使用 std::cref 时,延迟消失。很好发现。 @Omnifarious:我不确定这是否是可取的。闭包的预期行为(本质上是bind 的行为)是,只要闭包存在,作为参数传入的对象就会“存活”。如果bind 仅存储引用类型的所有参数的引用,则不会出现这种情况。或者,换一种方式来看:复制所有参数是一种安全的默认行为。传递引用具有一定的危险,因此应明确要求;此外,明确的refcref 是以后进行维护的任何人的明确标志。 使用了 ref 并且有效。我这样使用它:线程一(TestFunc,ref(vTest));因此,就线程而言,除非您使用 ref(),否则默认情况下似乎会复制变量。我现在正在查找 ref()。 @Columbo:是的,默认情况下会复制参数。 std::thread 在这方面与std::bind 具有相同的语义。【参考方案2】:

这里的线程在哪里?看起来for 循环导致了您所指的 延迟。这里没有什么不寻常的 - 因为您正在分配一个大小为 200000000 的向量。

【讨论】:

-1:如果在看到“V created”之间没有延迟,这将是一个很好的答案。和“在”。

以上是关于通过引用向量传递的线程函数启动缓慢的主要内容,如果未能解决你的问题,请参考以下文章

通过引用传递向量然后调用清除

C++:试图理解通过引用传递向量

通过引用传递向量内联

通过引用传递 - 左值和向量

通过引用传递向量 C++

C++ 通过引用传递向量字符指针