gpt4 book ai didi

具有函数返回值的 C++ 线程

转载 作者:太空狗 更新时间:2023-10-29 23:00:36 26 4
gpt4 key购买 nike

我有一个函数 myf 将一系列处理器编号作为参数并返回 true。并且 true 值的数量应该等于系统可用的处理器总数。但是,当我运行这个程序时,我得到的真值数量总是少于处理器数量。

有人可以帮我解决这个问题吗?

此处显示原型(prototype)示例:

// Header
bool myf(int startIndex, int endIndex)
{
return true;
}

int main(int argc, char** argv)
{
uint data_size = 9260; // Number of data points, here is an arbitrary large number.
int startIndex, endIndex; // Processor index.
int ncpus = sysconf(_SC_NPROCESSORS_ONLN); // Get number of processors.
int PerCPU = data_size / ncpus; // Data points per CPU.

std::thread t[ncpus];
vector<bool> test(ncpus, false); // Variable to collect return values from the myf.

for(int icpu = 0; icpu < ncpus; icpu++)
{
startIndex = icpu * PerCPU;
endIndex = startIndex + PerCPU;

if(((uint) endIndex > data_size)
|| ((icpu == ncpus - 1) && ((uint) endIndex < data_size)))
endIndex = data_size;

// Evaluate function value at each thread.
t[icpu] = std::thread([&] { test[icpu] = myf(startIndex, endIndex); });
}

// Join all threads.
for(int icpu = 0; icpu < ncpus; icpu++)
{
t[icpu].join();
}

// Count output from all the threads.
uint bool_size=0;
for(uint icpu = 0; icpu < test.size(); icpu++)
{
bool_size += test[icpu];
}

// Output should be 64, if ncpus = 64.
cout << " bool_size :: " << bool_size << std::endl;

return 0;
}

编译过程:

g++ main.cpp -pthread -std=c++0x

最佳答案

您描述的问题是由于主线程循环中索引计数器的增加导致线程异步执行造成的。

for(int icpu = 0; icpu < ncpus; icpu++) {
/* ... */
t[icpu] = std::thread([&] { test[icpu] = myf(startIndex, endIndex); });
}

在这里,每个线程都被传递一个 lambda,它通过引用(包括索引计数器 icpu)捕获它使用的所有对象。因此,线程的异步执行导致索引的读取与增量不同步,,索引可能在线程时已经递增读它。因此,true 的值有时存储在 vector test 中的错误索引处。

此外,这是未定义的行为,因为同时读取和写入同一内​​存 (icpu) 会导致数据竞争

示例:

------ Main thread ------
1. Index is 0 |----------- Thread 1 ------------|
2. Thread 1 is created | |
3. Index is 1 | |---------- Thread 2 -----------
4. Thread 2 is created | Thread 1 reads index 1 here |
5. Index is 2 | | Thread 2 reads index 2 here
6. Thread 3 is created | |
...

解决这个问题的一种方法是简单地让 lambda 通过 value 捕获 icpu(制作一个拷贝)。

t[icpu] = std::thread([&, icpu] { test[icpu] = myf(startIndex, endIndex); });

Live example

†​​ 请记住,线程执行顺序是由操作系统安排的。

关于具有函数返回值的 C++ 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33399354/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com