1

私はこの問題を抱えています。いくつかのジョブを実行するためにManagerいくつかの を作成する がWorkerあり、各ワーカーはスレッドを起動します。コードは次のようになります。

void Manager::create_workers(int n)
{
    _workers_vec.push_back( Worker() );  //save workers in Manager::_workers_vec
    _workers_vec.back().start();  //call the newly created worker's start() to fire a thread
}

void Worker::start()
{
    pthread_create(&_thread_id, NULL, routine, this);  //here is the problem
}

問題は、Workerのスレッド ルーチンが のthis一部のデータ メンバーを使用するためにルーチン引数として使用されますWorkerが、オブジェクトが作成されてにWorkerプッシュバックされることです。その間、古いオブジェクトは新しく割り当てられたスペースにコピーされ、その後破棄されます。Manager::_workers_vec_workers_vecWorkerWorker

これによりSegment fault、スレッドroutineが実行thisされ、渡された引数として使用され、の展開this中に破棄されるため、 が発生vectorします。

_workers_vecからvector<Worker>に変更する以外に、引数で渡されたvector<Worker *>を処理する方法について何か良いアイデアはありますか?routine

4

3 に答える 3

2

ベクトルを使用する理由によって異なります。代わりに std::deque を使用できます。deque は成長しても再割り当てされず、データはチャンクに格納され、容量を超えて成長すると新しいチャンクが deque に追加されます。

したがって、両端キューのデータは連続していないため、それが懸念される場合は、コンパイル時にコンテナーのサイズがわかっている場合は std::array を使用できます。実行時にわかっている場合は、std::vector を使用できます。 reserve() を使用して、必要な量のメモリを割り当てます。

コンテナーに一定時間アクセスする必要がない場合は、リンクされたリストを使用することもできます。

あるいは、C++11 または std::shared_ptr を使用している場合は、std::unique_ptr でベクトルを使用できます。

于 2012-08-10T06:05:42.377 に答える
2

さて、あなたはすでに答えを得たと思います-ポインター。それとは別に似ていますが、boost::shared_ptr や std::shared_ptr (C++11 標準を使用できる場合) などのスマート ポインターを使用することです。

于 2012-08-10T05:52:26.980 に答える
0

ベクトルが必要ない理由を説明してください。すべてのソリューションは、ある時点でポインターを使用すると思います。コンテナをベクトルではなくリストに変更することもできますが、これは基本的に、ポインタを使用し、ヒープ上のすべてのワーカーを割り当てることを意味します。

于 2012-08-10T05:55:42.220 に答える