34

新しい C++ 標準ライブラリを使用して複数のスレッドを作成し、それらのハンドルを配列に格納する方法を学びたいです。
どうすればスレッドを開始できますか?
私が見た例では、コンストラクターでスレッドを開始しましたが、配列を使用すると、コンストラクターを呼び出すことができません。

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

}
4

2 に答える 2

73

特別なことは何も必要ありません。割り当てを使用するだけです。ループ内で、次のように記述します

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

そしてそれはうまくいくはずです。

于 2012-05-19T05:13:07.663 に答える
-4

C++0x / C++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;
}
于 2012-05-19T03:06:48.657 に答える