1

私はスレッド化(およびその点についてはC/C++)が初めてで、複数のスレッドを使用して共有変数にアクセスしようとしています。

主に、変数 char inputarray[100]; を作成しました。

スレッド 1: このスレッドは、stdin から 2 バイト バーストでデータを読み取り、inputarray に追加します。(ファイルをフィードして入力)

スレッド 2: このスレッドは、一度に 1 バイトずつデータを読み取り、計算を実行し、そのデータを出力配列に入れます。

スレッド 3: このスレッドは、出力配列から 2 バイト バーストでデータを出力します。(標準出力)

入力部分を試みて、構造体を渡して動作させましたが、構造体を使用せずに実行したいのですが、問題が発生しています。

インプットを下に置くことができれば、同様の戦略を使用してアウトプットを完了することができると確信しています。どんな助けでも大歓迎です。

以下は、入力スレッドの大まかなテンプレートです。

#include <stdio.h>
#include <pthread.h>

using namespace std;

void* input(void* arg) {
    char reading[3];
    fread(reading,1,2,stdin);

    //append to char inputarray[]..???
}

int main() {
    char inputarray[100];
    pthread_t t1;
    pthread_create(&t1, NULL, &input, &inputarray);
    void *result;
    pthread_join(t1,&result);
    return 0;
}  
4

2 に答える 2

8

いくつかの問題:

  1. スタック上の配列は共有変数には非常に悪い選択だと思います。これはサイズが固定されており、スレッド 2 と 3 から新しい要素を配置する場所や要素を読み取る場所が明確でないためです。std::vectororstd::deque代わりに使用することを提案します。最初、コンテナは空です。次に、スレッド 2 がいくつかの要素をプッシュします。スレッド 3 はコンテナーをポーリング (または条件変数で待機) しており、新しい要素が見つかったら、それらを出力します。

  2. 共有変数へのアクセスをミューテックスと同期する必要があります (pthread ミューテックスstd::mutexまたはを検討してくださいboost::mutex)。条件変数を使用して、キュー内の新しい要素についてスレッド 3 に通知することもできます。ただし、最初の実装では必要ありません。

  3. 本当に pthread プリミティブを使用する必要がありますか? std::thread通常、 , std::mutex(最新のコンパイラを使用している場合) またはboost::thread,を使用する方がはるかに簡単で安全です (つまり、例外安全性) boost::mutex

于 2012-10-06T15:29:39.443 に答える
2

あなたは正しい方向に進んでいます:

注意として、pthreadsライブラリはC libであるため、コールバックをC関数として宣言する必要があります。

extern "C" void* input(void* arg);

個人的には、最初の要素のアドレスを渡します。

pthread_create(&t1, NULL, &input, &inputarray[0]);

これにより、コードは次のようになります。

void* input(void* arg) {

    try
    {
       char*  inputarray    = (char*)arg;
       size_t inputLocation = 0;

       // Need to make sure you don't over run the buffer etc...
       while(!finished())
       {
          fread(&inputarray[inputLocation],1,2,stdin);
          inputLocation += 2;
       }
    }
    catch(...){} // Must not let exceptions escape a thread.
    return NULL;
}

このスタイルの問題は、個々のスレッドに調整の責任を負わせることです。ライタースレッドは終了をチェックする必要があり、リーダースレッドは利用可能なデータなどがあるかどうかをチェックする必要があります。これにはすべて調整が必要なので、共有ミューテックスと条件変数が必要になります。

より良い選択は、その責任をコミュニケーションを行うオブジェクトに移すことです。したがって、通信に必要な基本操作を含むクラスを作成し、そのメソッドに適切なチェックを実行させます。

 class Buffer
 {
     public:
        void write(......); //
        void read(.....);   //
     private:
        // All the synchronization and make sure the two threads
        // behave nicely inside the object.
 };

 int main()
 {
       pthread_t threads[3];
       std::pair<Buffer, Buffer>   comms;
       // comms.first     inputToRead
       // comms.second    processesToOutput


       pthread_create(&threads[0], NULL, &readInput, &comms.first);   // Input
       pthread_create(&threads[1], NULL, &procInput, &comms);         // Processing
       pthread_create(&threads[2], NULL, &genOutput, &comms.second);  // Output

       void *result;
       pthread_join(threads[0],&result);
       pthread_join(threads[1],&result);
       pthread_join(threads[2],&result);

 }

補足として:

データの処理について非常に奇妙なことがない限り。これはおそらく、シングルスレッドアプリケーションとしてより高速に記述されます。

于 2012-10-06T15:39:58.723 に答える