1

这是我的代码:

vector<MyClass> objs;
objs.resize(4);

vector<thread> multi_threads;
multi_threads.resize(4);

for(int i = 0; i < 4; i++)
{
    multi_threads[i] = std::thread(&MyFunction, &objs[i]);  
                   // each thread change some member variable in objs[i]
    multi_threads[i].join();
}

我希望objs可以在每个线程中更改元素。然后在线程完成后,我可以访问成员数据。

但是,当程序完成上述循环时,我想获取的成员变量根本没有改变。

我猜这是因为 C++ 中的多线程机制,但我不知道我到底做错了什么。我可以知道如何实现我的期望吗?

非常感谢。

==================================================== ================================ 编辑:

这里是源代码MyFunc

void MyFunc(MyClass &obj)
{
    vector<thread> myf_threads;
    myf_threads.resize(10);
    for(int i = 0; i < 10; i++)
    {
        myf_threads[i] = std::thread(&AnotherClass::increaseData, &obj);
        myf_threads[i].join();
    }
 }

这是AnotherClass::increaseData

void AnotherClass::increaseData(Myclass& obj)
{
    obj.add();
}

void MyClass::add()
{
    data++;
}
4

2 回答 2

3

objs首次访问时为空,导致未定义的行为:

multi_threads[i] = std::thread(&MyFunction, &objs[i]);
                                           //^^ 'objs' is empty, so this access
                                           // is out-of-bounds.

在访问它之前必须有MyClasswithin的实例。通过预先分配所需数量的元素,objs避免潜在的内部缓冲区重新分配。objs vector如果发生重新分配,先前获得的指针将悬空:

std::vector<MyClass> objs(4);
std::vector<std::thread> multi_threads(objs.size());

join()为了避免在后续循环中而不是在创建循环中顺序执行线程:

for(int i = 0; i < 4; i++)
{
    multi_threads[i] = std::thread(&MyFunction, &objs[i]);
}

for (auto& t: multi_threads) t.join();

演示


更新后,线程使用的函数似乎正在引用一个实例,而不是指针MyClass(即使指针被传递给std::thread构造函数?)。在这种情况下,std::ref(objs[i])必须使用,以避免构造函数复制MyClass实例std::thread(参见演示)。std::thread::thread()参考页面的注释:

线程函数的参数按值复制。如果需要将引用参数传递给线程函数,则必须对其进行包装(例如,使用std::refor std::cref)。

于 2013-08-13T10:22:02.957 回答
0

也许

std::ref(objs[i])

帮助你。我对线程函数中的引用参数有同样的问题,这对我有帮助。

于 2013-08-13T11:25:46.223 回答