在几个池上拆分线程



我有一些类似的代码:

void doSth () {// code ...}
vector<string> files_1; // filenames .txt to get text from
vector<string> files_2; // filenames .txt to get text from
// sizes of files_1 and files_2 are ==
mutex m;
// lambda for for_each
auto gogogo= [&](const string& fn1) {
// Comupute other element via pointer arthimetics
// Works only with vector, for, say, deque, use container of struct
const string& fn2 = files_2[&fn1 - files_1.data()];

// do whatever I need in this doSth function
doSth(fn1, fn2);
// avoid doing any real work under the lock to benefit from paralleling
lock_guard<mutex> guard(m);
};
// start threads
for_each(execution::par, files_1.begin(), files_1.end(), gogogo);

现在for_each语句执行lambda的次数与files_1.size()的次数一样多。如果它有40,它将在for_each中执行lambda40次。我想要files_1&files_2将在for_each语句中以8乘8执行(每个下一个8应该只在前一个8执行之后调用,而不是一次调用所有8(。我怎么能那样做?我需要在每8次之后释放内存吗?(如果files_1.size()的大小很大,RAM是一个问题,这就是为什么我想按8乘8的顺序进行(。如果你有任何问题,请问我。

我使用mingw64g++ 9.2visual studio 2017 c++17windows 10 os

Now lambda do this :
filename1.txt
filename2.txt
filename3.txt
filename4.txt
filename5.txt
filename6.txt
filename7.txt
filename8.txt
filename9.txt
filename10.txt
filename11.txt
filename12.txt
filename13.txt
filename14.txt
filename15.txt
filename16.txt
filename17.txt
I want it to be executed like this:
filename1.txt
filename2.txt
filename3.txt
filename4.txt
filename5.txt
filename6.txt
filename7.txt
filename8.txt
// Previous 8 files executed successfully, next 8
filename9.txt
filename10.txt
filename11.txt
filename12.txt
filename13.txt
filename14.txt
filename15.txt
filename16.txt
// prev 8 executed, next
filename17.txt
// ...

您必须将for_each()放入一个循环中,并为其提供间隔8个元素的迭代器。这里有一个可能的解决方案:

#include <iterator>
...
for(auto i = files_1.begin(); i != files_1.end();) {
auto start = i;
auto end = std::advance(i, std::min(8, std::distance(i, files_1.end()));
for_each(execution::par, start, end, gogogo);
i = end;
}

通过使用for_each_n(),以及它在刚刚处理的范围之后向元素返回迭代器的事实,您可以写得更简洁:

for(auto i = files_1.begin(); i != files_1.end();) {
auto count = std::min(8, std::distance(i, files_1.end()));
i = for_each_n(execution::par, i, count, gogogo);
}

最新更新