我有下面的最小工作示例,其中我在向量chains中创建了许多chains对象,在向量workers中创建了相同数量的thread对象,每个对象在每个对应的markov_chain对象上执行一个markov_chain类成员函数sample。该函数接受一些整数(在下面的示例中为99),并将其分配给markov_chain对象的markov_chain公共数据成员。然后,为向量中的每个对象打印acceptance的值。
#include <iostream>
#include <thread>
#include <algorithm>
#include <vector>
class markov_chain
{
public:
unsigned int length{0}, acceptance{0};
markov_chain(unsigned int l) {length=l;}
~markov_chain() {}
void sample(int acc);
};
void markov_chain::sample(int acc)
{
acceptance = acc;
std::cout << length << ' ' << acceptance << std::endl;
}
int main()
{
int number_of_threads{3};
int number_of_samples{1000};
std::vector<markov_chain> chains;
std::vector<std::thread> workers;
for (int i = 0; i <= number_of_threads; i++) {
chains.push_back(markov_chain(number_of_samples));
workers.push_back(std::thread(&markov_chain::sample, chains[i], 99));
}
std::for_each(workers.begin(), workers.end(), [](std::thread &t)
{
t.join();
});
for (int i = 0; i <= number_of_threads; i++) {
std::cout << chains[i].length << ' ' << chains[i].acceptance << std::endl;
}
return 0;
}在执行时,程序输出
1000 99
1000 99
1000 99
1000 99
1000 0
1000 0
1000 0
1000 0因此,程序未能为向量acceptance中的对象更改chains值。我不知道为什么会发生这种情况;函数sample在不创建线程的情况下成功地分配了所需的值。
发布于 2021-05-17 21:57:49
您的代码有两个问题:
std::thread时,您将每个对象的一个副本作为sample()的this参数传递。chains向量可能会导致向量重新分配其内部数组,从而使您已经传递给现有线程的任何对象指针无效,因为这些原始对象现在在重新分配之后消失了。在创建任何线程之前,您需要完全初始化chains向量。您需要将指向每个对象的指针传递给每个线程。
您可以预先对数组进行reserve(),以避免在插入数组时重新分配,例如:
int main()
{
int number_of_threads{3};
int number_of_samples{1000};
std::vector<markov_chain> chains;
std::vector<std::thread> workers;
chains.reserve(number_of_threads);
for (int i = 0; i < number_of_threads; ++i) {
chains.push_back(markov_chain(number_of_samples));
workers.push_back(std::thread(&markov_chain::sample, &chains[i], 99));
}
for(auto &t : workers) {
t.join();
}
for (auto &c : chains) {
std::cout << c.length << ' ' << c.acceptance << std::endl;
}
return 0;
}但是,由于所有对象都是用相同的初始值初始化的,一个更简单的方法是完全摆脱chains.push_back(),而使用chains.resize(),例如:
int main()
{
int number_of_threads{3};
int number_of_samples{1000};
std::vector<markov_chain> chains;
std::vector<std::thread> workers;
chains.resize(number_of_threads, markov_chain(number_of_samples));
for (int i = 0; i < number_of_threads; ++i) {
workers.push_back(std::thread(&markov_chain::sample, &chains[i], 99));
}
for(auto &t : workers) {
t.join();
}
for (auto &c : chains) {
std::cout << c.length << ' ' << c.acceptance << std::endl;
}
return 0;
}或者,甚至使用vector构造函数本身:
int main()
{
int number_of_threads{3};
int number_of_samples{1000};
std::vector<markov_chain> chains(number_of_threads, markov_chain(number_of_samples));
std::vector<std::thread> workers;
for (int i = 0; i < number_of_threads; ++i) {
workers.push_back(std::thread(&markov_chain::sample, &chains[i], 99));
}
for(auto &t : workers) {
t.join();
}
for (auto &c : chains) {
std::cout << c.length << ' ' << c.acceptance << std::endl;
}
return 0;
}https://stackoverflow.com/questions/67577365
复制相似问题