1

問題: いくつかのテキスト ファイル (10 個) があり、すべての行に数字が含まれています。pthread ライブラリを使用して作成したいくつかのスレッドに分割する必要があります。作成されたこれらのスレッド (ワーカー スレッド) は、送信された最大の素数 (およびすべてのテキスト ファイルからの最大の素数) を見つけます。

解決策に関する私の現在の考え: 2 つの配列とすべてのテキスト ファイルを 1 つの配列に入れ、もう 1 つの配列には 1000 行と読み込んで、そのバイナリ ファイルのインデックスへのポインターを送信できるバイナリ ファイルを含めることを考えています。 ID、ファイルポインター、およびファイル位置を含む構造体で、それをクランクさせます。

私が話していることの少し:

pthread_create(&threads[index],NULL,workerThread,(void *)threadFields[index]);//Pass struct to each worker

構造:

typedef struct threadFields{
  int *id, *position;
  FILE *Fin;
}tField;

誰かが何か洞察やより良い解決策を持っているなら、それは大歓迎です

編集:わかりましたので、問題の解決策を見つけました.SaveTheRbtzが提案したものと似ていると思います. 私が実装したものは次のとおりです。ファイルを取得して 1 つのバイナリ ファイルにマージし、ループ内でそれを追跡しました (各エントリのバイト数を考慮する必要があり、これはハードコードされていました)。

struct threadFields *info = threadStruct;
  int index;
  int id = info->id;
  unsigned int currentNum = 0;
  int Seek = info->StartPos;
  unsigned int localLargestPrime = 0;
  char *buffer = malloc(50);
  int isPrime = 0;

    while(Seek<info->EndPos){
    for(index = 0; index < 1000; index++){//Loop 1000 times
    fseek(fileOut,Seek*sizeof(char)*20, SEEK_SET);
    fgets(buffer,20,fileOut);
    Seek++;
    currentNum = atoi(buffer);
    if(currentNum>localLargestPrime && currentNum > 0){
      isPrime = ChkPrim(currentNum);
      if( isPrime == 1)
        localLargestPrime = currentNum;
    }
  }
4

2 に答える 2

1

それぞれが引数として指定されたファイルを処理する 10 個のスレッドを実行できますか? 各スレッドは独自のファイルを読み取り、値がこれまでに記録した最大の素数よりも大きいかどうかをチェックし、大きい場合は、新しい数が素数であることをチェックします。次に、終了時に、コーディネーター スレッドに素数を返すことができます。コーディネーター スレッドは、スレッドが終了するのを待って、各スレッドから最大の素数を収集し、最大のものだけを保持します。おそらく 0 をセンチネル値として使用して、「素数が (まだ) 見つからない」ことを示すことができます。

10 ではなく 11 のスレッドが必要だったとしましょう。その場合、ワークロードをどのように分割しますか?

pthread_exit()すぐに 11 番目のスレッドを実行してもらいます。自分で調整の問題を作成したい場合は、それを行うことができますが、必要以上に人生を難しくするのはなぜですか.

絶対に 11 個のスレッドで 10 個のファイルを処理し、作業を分割する必要がある場合は、最初に 10 個のファイル ストリームのセットをキューに入れることになると思います。スレッドは、「キューが空でない」という条件で待機して、ファイル ストリームを取得します (ミューテックスと条件など)。スレッドがファイル ストリームを取得すると、ファイルから 1 つの数値を読み取り、そのストリームをキューにプッシュして (シグナリング キューが空ではない)、その数値を処理します。EOF では、スレッドはファイルを閉じ、それをキューにプッシュしません (そのため、スレッドは「未読データが残っているファイル ストリームがない」ことを検出する必要があります)。これは、実際に読み取る数値の素数計算にかかる時間に応じて、各スレッドがデータの約 11 分の 1 を読み取ることを意味します。これは、ファイルごとに 1 つのスレッドという単純なソリューションよりも、はるかに、はるかに、はるかに難しいコードです。ただし、(多かれ少なかれ)任意の数のスレッドとファイルにスケーリングします。特に、7 つのスレッドで 10 個のファイルを処理する場合や、17 個のスレッドで 10 個のファイルを処理する場合に使用できます。

于 2012-12-08T17:10:18.910 に答える
0

メッセージ キューのジョブのように見えます。

  1. データをチャンクに分割してからキューに入れる「サプライヤー」スレッドのセット。あなたの場合、チャンクはファイル名または(fd、オフセット、サイズ)タプルで表すことができます。簡単にするために、そのようなサプライヤが 1 つ存在する場合があります。
  2. 入力キューからデータをプルして処理し、結果を別のキューに入れる「ワーカー」スレッドの数。パフォーマンス上の理由から、通常は多くのワーカーが存在します。たとえば、タスクが CPU 集中型の場合sysconf(_SC_NPROCESSORS_ONLN)は、適切な選択です。
  3. 結果キューを単一の値に「削減」する 1 つの「アグリゲーター」スレッド。あなたの場合、それは単純なmax()機能です。

これは非常にスケーラブルなソリューションであり、さまざまな種類の処理ステージを簡単に組み合わせて、理解しやすいパイプラインにすることができます。

于 2012-12-09T16:47:46.723 に答える