11

私は C++ でプログラミングしていますが、pthread.h のみを使用しており、ブーストや C++11 スレッドは使用していません。

したがって、スレッドを使用しようとしていますが、以前の質問(リンク)の 1 つに基づいて、タスクの完了直後にスレッドが終了するため、これは実行可能ではないようであり、スレッドプール実装を使用するより一般的な理由の 1 つです。これらのスレッドを複数のタスクに再利用することで、スレッド作成のオーバーヘッドを削減することです。

これを C で実装して fork() を使用し、メインから子プロセスへのパイプを作成する唯一の方法はありますか? または、私が知らないスレッドとその親の間にパイプを設定する方法はありますか?

よろしくお願いします!

4

6 に答える 6

6

はい、スレッド間にスレッドセーフキューを作成できます。次に、プール内のスレッドはループ内にあり、キューからアイテムを取得し、必要なものを実行してから、戻って別のアイテムを取得します。

これは、C ++では一般的に少し簡単/簡単です。これは、一部のインターフェイス(たとえば、operator()タスクのコードを実行するためのオーバーロード)について合意するのが少し簡単だからですが、基本的なレベルでは、Cですべて同じことを実行できます(たとえば、 、taskキューに入れる各構造体には、そのタスクの作業を実行するための関数へのポインターが含まれます)。

あなたの場合、C ++を使用しているので、オーバーロードを使用operator()して作業を行う方がおそらく簡単です。構造体の残りの部分task(またはそれを呼び出すために選択したもの)には、必要なデータなどが含まれます。

于 2012-05-04T15:47:28.473 に答える
3

POSIX標準から:

int pthread_create(pthread_t *restrict thread,
   const pthread_attr_t *restrict attr,
   void *(*start_routine)(void*), void *restrict arg);

(...)スレッドは、唯一の引数として実行start_routineして作成されます。arg

したがって、この関数を使用して一連のスレッドを作成し、それらすべてに次のような関数を実行させる必要があります。

void *consumer(void *arg)
{
    WorkQueue *queue = static_cast<WorkQueue *>(arg);

    for (task in queue) {
        if (task == STOP_WORKING)
            break;
        do work;
    }
    return WHATEVER;
}

(入力の最後に、n個 STOP_WORKINGのアイテムをキューにプッシュします。nはスレッドの数です。)

念のために言っておきますが、pthreadsは非常に低レベルのAPIであり、型の安全性はほとんどありません(すべてのデータはvoidポインターとして渡されます)。CPUを集中的に使用するタスクを並列化しようとしている場合は、代わりにOpenMPを検討することをお勧めします。

于 2012-05-04T15:46:24.090 に答える
2

Apple の Grand Central Dispatch の基礎であり、スレッド プールを使用するlibdispatch のソース コードを調べると役立つ場合があります。

于 2012-05-04T16:00:58.887 に答える
2

「スレッドはタスクの完了直後に終了するため、実行可能とは思えません」何??

for(;;){
  Task *myTask=theCommonProducerConsumerQueue->pop();
  myTask->run();
}

.. 何も返さない、実際には返さない。

于 2012-05-04T15:51:12.280 に答える
1

インテルのスレッドビルディングブロックを使用して、ワークキュー/スレッドプールのようなタスクを実行することをお勧めします。TBB 3.0を使用したかなり工夫された例:

class PoorExampleTask : public tbb::task {
    PoorExampleTask(int foo, tbb::concurrent_queue<float>& results)
    : _bar(foo), _results(results)
    { }

    tbb::task* execute() {
        _results.push(pow(2.0, foo));
        return NULL;
    }

private:
    int _bar;
    tbb::concurrent_queue<float>& _results;
}

後でそのように使用されます:

tbb::concurrent_queue<float> powers;
for (int ww = 0; ww < LotsOfWork; ++ww) {
    PoorExampleTask* tt
        = new (tbb::task::allocate_root()) PoorExampleTask(ww, powers);
    tbb::task::enqueue(*tt);
}
于 2012-05-04T16:08:36.590 に答える
-2

http://people.clarkson.edu/~jmatthew/cs644.archive/cs644.fa2001/proj/locksmith/code/ExampleTest/threadpool.c

数か月前に Google を使用したので、ぜひ試してみてください。

編集: 代わりにグループが必要なようです。ワーカーが作業を実行せず、スレッドに参加するだけになるように、上記を少し変更して作成することができました。

于 2012-05-04T15:55:49.580 に答える