Ответ 1
Ничего не требуется; просто используйте назначение. Внутри вашей петли напишите
myThreads[i] = std::thread(exec, i);
и он должен работать.
Я хочу узнать, как создать несколько потоков с новой стандартной библиотекой С++ и сохранить их дескрипторы в массиве.
Как я могу начать поток?
В примерах, которые я видел, начинается поток с конструктором, но если я использую массив, я не могу вызвать конструктор.
#include <iostream>
#include <thread>
void exec(int n){
std::cout << "thread " << n << std::endl;
}
int main(int argc, char* argv[]){
std::thread myThreads[4];
for (int i=0; i<4; i++){
//myThreads[i].start(exec, i); //?? create, start, run
//new (&myThreads[i]) std::thread(exec, i); //I tried it and it seems to work, but it looks like a bad design or an anti-pattern.
}
for (int i=0; i<4; i++){
myThreads[i].join();
}
}
Ничего не требуется; просто используйте назначение. Внутри вашей петли напишите
myThreads[i] = std::thread(exec, i);
и он должен работать.
С С++ 0x/С++ 11 попробуйте использовать векторы вместо массивов потоков; что-то вроде этого:
vector<thread> mythreads;
int i = 0;
for (i = 0; i < 8; i++)
{
mythreads.push_back(dostuff, withstuff);
}
auto originalthread = mythreads.begin();
//Do other stuff here.
while (originalthread != mythreads.end())
{
originalthread->join();
originalthread++;
}
Редактирование: если вы действительно хотите обработать выделение памяти самостоятельно и использовать массив указателей (т.е. векторы просто не ваши), то я не могу рекомендовать valgrind достаточно высоко. Он имеет блокировки выделения памяти и проверки потоков и т.д. И т.д. Бесценный для такого рода вещей. В любом случае, здесь пример программы, использующей массив выделенных вручную потоков, и он очищается после себя (без утечек памяти):
#include <iostream>
#include <thread>
#include <mutex>
#include <cstdlib>
// globals are bad, ok?
std::mutex mymutex;
int pfunc()
{
int * i = new int;
*i = std::rand() % 10 + 1;
// cout is a stream and threads will jumble together as they actually can
// all output at the same time. So we'll just lock to access a shared
// resource.
std::thread::id * myid = new std::thread::id;
*myid = std::this_thread::get_id();
mymutex.lock();
std::cout << "Hi.\n";
std::cout << "I'm threadID " << *myid << std::endl;
std::cout << "i is " << *i << ".\n";
std::cout << "Bye now.\n";
mymutex.unlock();
// Now we'll sleep in the thread, then return.
sleep(*i);
// clean up after ourselves.
delete i;
delete myid;
return(0);
}
int main ()
{
std::thread * threadpointer = new std::thread[4];
// This seed will give us 5, 6, 4, and 8 second sleeps...
std::srand(11);
for (int i = 0; i < 4; i++)
{
threadpointer[i] = std::thread(pfunc);
}
for (int i = 0; i < 4; i++)
// Join will block our main thread, and so the program won't exit until
// everyone comes home.
{
threadpointer[i].join();
}
delete [] threadpointer;
}