Подтвердить что ты не робот

Как создать массив объектов потока в С++ 11?

Я хочу узнать, как создать несколько потоков с новой стандартной библиотекой С++ и сохранить их дескрипторы в массиве. Как я могу начать поток?
В примерах, которые я видел, начинается поток с конструктором, но если я использую массив, я не могу вызвать конструктор.

#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();
    }

}
4b9b3361

Ответ 1

Ничего не требуется; просто используйте назначение. Внутри вашей петли напишите

myThreads[i] = std::thread(exec, i);

и он должен работать.

Ответ 2

С С++ 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;
}