2011-12-10 9 views
0

ワーカースレッドとファシリテータスレッドを正しく同期させるのに問題があります。私が解決しようとしている問題は、最大10個のスレッドを使用する最大の素数10個のファイルを見つけることです。 1つのスレッドはシングルスレッドであり、それより大きいものはマルチスレッドです。問題は、作業者がファシリテーターに新しいプライムを見つけたことを知らせる場合です。ファシリテータは、番号が重要でない場合は無視し、すべてのスレッドを更新するように通知します。my_latest_lgprime私は私の脳とコードに詰まっています。ワーカースレッドとコントローラスレッドの同期

タスクは、ファシリテーターと同期を使用して完了する必要があります。ここで

は、私がこれまで持っているものです。

ワーカー:

void* worker(void* args){ 
    w_pack* package = (w_pack*) args; 
    int i, num; 
    char text_num[30]; 
    *(package->fac_prime) = 0; 
    for(i = 0; i<package->file_count; i++){ 
      int count = 1000000; //integers per file 
      FILE* f = package->assigned_files[i]; 
      while(count != 0){ 
       fscanf(f, "%s", text_num); 
       num = atoi(text_num); 
       pthread_mutex_lock(&lock2); 
       while(update_ready != 0){ 
        pthread_cond_wait(&waiter, &lock2); 
        package->my_latest_lgprime = largest_prime;//largest_prime is global 
        update_ready = 0; 
       } 
       pthread_mutex_unlock(&lock2); 
       if(num > (package->my_latest_lgprime+100)){ 
        if(isPrime(num)==1){ 
         *(package->fac_prime) = num; 
         package->my_latest_lgprime = num; 
         pthread_mutex_lock(&lock); 
         update_check = 1; 
         pthread_mutex_unlock(&lock); 
         pthread_cond_signal(&updater); 
        } 

       } 
       count--; 
      } 
    } 

    done++; 
    return (void*)package; 
}` 

がファシリテーター:誰もがいずれかを持っている場合は

void* facilitator(void* args){ 
    int i, temp_large; 
    f_pack* package = (f_pack*) args; 

    while(done != package->threads){ 
      pthread_mutex_lock(&lock); 
      while(update_check == 0) 
       pthread_cond_wait(&updater, &lock); 
      temp_large = isLargest(package->threads_largest, package->threads); 
      if(temp_large > largest_prime){ 
       pthread_mutex_lock(&lock2); 
       update_ready = 1; 
       largest_prime = temp_large; 
       pthread_mutex_unlock(&lock2); 
       pthread_cond_broadcast(&waiter); 
       printf("New large prime: %d\n", largest_prime); 
      } 
      update_check = 0; 
      pthread_mutex_unlock(&lock); 
    } 
} 

ここでは、ワーカーパッケージ

typedef struct worker_package{ 
    int my_latest_lgprime; 
    int file_count; 
    int* fac_prime; 
    FILE* assigned_files[5]; 
} w_pack; 

ですどのように私が解決することができるアイデアセマフォを使用する方が簡単な場合は、私は助けに感謝します。

おかげ

答えて

1

私は実際に確実に問題を発見することはできませんが、ただ簡単にコードを読み取ることによって、まだそれが同期せずにアクセスし、変更されdone変数はスレッド間で共有されているようです。

いずれにしても、ソリューションを改善するための2つのアイデアを提案できます。

  1. 起動時に各スレッドにファイルのリストを割り当てます。これは、各ファイルの処理に多少の時間がかかるため、最も効率的な方法ではありません。 1つのファイルリストを持つ方が良い方法だと思われ、各スレッドはリストの次のファイルをピックアップします。

  2. これには実際にファシリテータのタスクが必要ですか?それは私自身の最大の素数を追跡することができ、新しい最大値を見つけるたびに必要に応じてグローバル最大値をチェックして更新することができます。単一の最大値(スレッドごとの最大値なし)を保持することもできますが、比較する必要があるたびにロックする必要があります。あなたはmax_global_number = 0を初期化する必要があり、ワーカースレッドを開始する前に

    while (true) { 
        lock(file_list_mutex) 
        if file list is empty { 
         break // we are done! 
        } 
        file = get_next_file_in_list 
        unlock(file_list_mutex) 
    
        max = 0 
        foreach number in file { 
         if number is prime and number > max { 
          lock(max_number_mutex) 
          if (number > max_global_number) { 
           max_global_number = number 
          } 
          max = max_global_number 
          unlock(max_number_mutex) 
         } 
        } 
    } 
    

    :ここ

は、私がワーカースレッドを書くだろうかの擬似コードです。

上記のソリューションは、あなたの場合のようにロックを悪用しないという利点があり、スレッドの競合が最小限に抑えられます。

+0

Miguelにお返事ありがとうございます。ファシリテータの目的は、スレッドが別のスレッドが見つけた可能性のあるプライムよりも小さい数字をスキップできるようにすることです。物事をより効率的にする必要がありますが、私の実装では、どのように考え出すことができません。ファイルの割り当てに関しては、スレッドが実行されているときにのみ、その点でより効率的にしようとはしていません。言い換えれば、私は、ファイルが割り当てられた後で作業者の時間を始めるでしょう。 –

+0

こんにちはトレバー。私はまだファシリテーターの仕事の必要性を見ません。あなたのソリューションはロックや条件を待つのに多くの時間を費やすことに注意してください。あなたが見ているすべての番号について、それがプライムではなくてもそうします。 10スレッドで多くの競合が発生します。あなたは本当にプロセスをより効率的にしているわけではありません。私のソリューションでは、スレッドは独自の最大値で動作し、スレッドが見つかるとロックします。また、その時点でロックが取られているので、あなたのソリューションのようにグローバルな最大値も取得します。 – Miguel

+0

+1の#2。私はファシリテーターのどちらかのポイントを実際には見ません、Trevor。新しいプライムを転記するときに各従業員が前にスキップして、すでにそこで高い価値を見つけているように簡単にすることができます。その点については、ファイルを最初にソートして作業することができます。最大の素数が見つかると、そのファイルで完了します。 – Duck

関連する問題