gpt4 book ai didi

c++ - 传递对线程的引用时,std::ref 真的有必要吗?

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

我正在阅读 C++ Concurrency in Action,在第 2 章中我被引导相信即使函数原型(prototype),例如:

void MagicFunc(Data& myData);

旨在像下面这样使用:

Data dataExample;
thread t(MagicFunc,dataExample);

我真的应该这样做

Data dataExample
thread t(MagicFunc,std::ref(dataExample));

否则,我预期发生在“dataExample”上的更改将不会发生。具体来说,它是这样的:

Although MagicFunc expects the second parameter to be passed by reference, the std::thread constructor t doesn’t know that; it’s oblivious to the types of the arguments expected by the function and blindly copies the supplied values. When it calls Magicfunc, it will end up passing a reference to the internal copy of data and not a reference to data itself. Consequently, when the thread finishes, these updates will be discarded as the internal copies of the supplied arguments are destroyed, and process_widget_data will be passed an unchanged Data myData rather than a correctly updated version.

但是,用下面的程序测试一下

#include <iostream>
#include <thread>
#include <vector>
#include <chrono>
#include <assert.h>
using namespace std;
using namespace std::chrono;

const int NUM_VALS = 50000000;

#define _MULTICORE

void AddValuesToSlots(vector<int>& vecVals,vector<int>::iterator& begin,
int num,int startNum){
int i = startNum;
auto end = begin + num;
for (auto itr = begin; itr < end; ++itr){
*itr = i++;
}
}

int main()
{
vector<int> vecVals;
vecVals.resize(NUM_VALS);

//get number of cores and divide up the workload
unsigned int numCores = thread::hardware_concurrency();
unsigned int slotsPerThread = NUM_VALS / numCores;

//for timing
high_resolution_clock::time_point t1 = high_resolution_clock::now();


thread* t = new thread[numCores];

//get the iterator to the beginning
auto begin = vecVals.begin();

#ifdef _MULTICORE
for (int core = 0; core < numCores; ++core){
t[core] = thread(AddValuesToSlots, vecVals, begin + core*slotsPerThread,
slotsPerThread, core*slotsPerThread);
}

for (int core = 0; core < numCores; ++core){
t[core].join();
}
#else
AddValuesToSlots(vecVals, begin, NUM_VALS, 0);
#endif


delete[] t;

//how long did it take?
high_resolution_clock::time_point t2 = high_resolution_clock::now();
cout << duration_cast<milliseconds>(t2-t1).count() << endl;

#ifdef _DEBUG
//test that the values are correct
for (int slot = 0; slot < NUM_VALS; ++slot)
assert(vecVals[slot] == slot);
#endif

return 0;
}

我试过将 vecVals 封装在 std::ref 中,如果没有,两次都可以毫无问题地执行。 std::ref 是否真的有必要并且提供的信息有误?

谢谢

最佳答案

您不会直接更改 vecVals。迭代器可以工作,因为复制迭代器是可以的,它仍然指向相同的内存地址

关于c++ - 传递对线程的引用时,std::ref 真的有必要吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29259529/

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