Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 函数引用和线程问题_C++_Multithreading_C++11_Reference_Bind - Fatal编程技术网

C++ 函数引用和线程问题

C++ 函数引用和线程问题,c++,multithreading,c++11,reference,bind,C++,Multithreading,C++11,Reference,Bind,我在我的虚拟linux机器(GCC 4.4.5-Debian)中使用以下测试程序随机测试std::thread: #include <algorithm> #include <thread> #include <iostream> #include <vector> #include <functional> using namespace std; static int i=0; void f( vector<int>

我在我的虚拟linux机器(GCC 4.4.5-Debian)中使用以下测试程序随机测试
std::thread

#include <algorithm>
#include <thread>
#include <iostream>
#include <vector>
#include <functional>
using namespace std;

static int i=0;
void f( vector<int> &test)
{
    ++i;
    cout << "Push back called" << endl;
    test.push_back(i);
}

int main()
{
    vector<thread> t;
    vector<int> test;
    for( int i=0; i<1000; ++i )
    {
        t.push_back( thread( bind(f, test) ) );
    }
    for( auto it = t.begin(); it != t.end(); ++it )
    {
        (*it).join();
    }
    cout << test.size() << endl;
    for( auto it = test.begin(); it != test.end(); ++it )
    {
        cout << *it << endl;
    }

    return 0;
}
它按顺序打印所有值,并且似乎工作正常。现在只剩下一个问题:这是幸运的(又称未定义行为(UndefinedBehavior,TM))还是静态变量在代码中导致了类似静默互斥的步骤


PS:我理解这里的“杀死多线程”问题,这不是我的重点。我只是想测试基本的
std::thread
功能的健壮性…

在我看来像是线程问题

虽然我不是100%确定,但应该注意的是,所有1000个线程:

  • 对同一个int值执行
    ++i
    (这不是一个原子操作-您可能会在这里遇到问题,您可以使用
    \uuu sync\u fetch\u和uu add(&i,1)
    )(请注意,它是一个gcc扩展,不是标准C++)

  • std::vector
    上同时执行
    push_-back
    ,这不是一个线程安全的容器,对
    cout
    也一样,我想。我相信你需要使用一个锁定机制来解决这个问题(
    std::mutex
    也许吧?到目前为止我只使用了pthreads,但我相信这正是你所需要的)

请注意,这种情况会扼杀在这里使用线程的任何好处,但这是由于您不应该在非线程安全的对象上同时使用多个线程


----编辑----

我在这个线程API上有一个google(不幸的是,我的tdm gcc 4.5在Windows上没有出现)。 立即而不是:

thread( bind(f, test) )
你可以说

thread( f, test )
并以这种方式传递任意数量的参数

资料来源:

这也解决了我以前没有注意到的向量复制的问题 (@villintehaspam此处为+1)


实际上,还需要做一件事来确保不在此处创建副本:

thread( f, std::ref(test) )
将确保未复制向量


哇,我也被搞糊涂了。

绑定实际上会生成向量的一个副本,这样每个线程都会返回到自己的副本上(是的,这在这里没有帮助)。您需要为线程提供指针或类似对象,以便它们使用相同的向量。您还应该确保使用Kos建议的访问保护


编辑:修复使用std::ref而不是复制向量后,多线程访问问题仍然存在。我的猜测是,您现在没有遇到任何问题的唯一原因是因为该示例非常简单(或者您可能只是在调试模式下尝试过)-无法自动保证++是原子的,因为int是静态的。

海报应该阻止多线程访问变量,这是正确的。这里的问题是绑定,但我投+1票,因为在绑定修复后这将是一个问题。
thread(f,test)
调用似乎在内部使用了类似于
bind
的东西,因为我在这里也得到了向量复制行为。(另外:太糟糕了,
std::thread
对mingw不可用……mingw-w64项目正在处理它,但它还没有完成:()
boost::bind
默认情况下是否也以这种方式运行?是否有语法使
std::bind
按照OP的预期通过引用传递向量?
std::bind(f,std::ref(test))
也许吧?只是一个猜测:)@DeadMG:1)GCC4.4不支持它们,2)不知道非常混乱的语法
:D
+事实是
std::thread
构造函数似乎减轻了对
std::bind
@rubenvb:Update to GCC4.5的需要?语法没那么糟糕。@DeadMG:我明白了,完全理解你的意思。:),但我也在忙着做其他事情。。。这只是一个无法控制的小思想实验。。。
thread( f, std::ref(test) )