2016-06-23 18 views
-1

私は解決できない問題があります。 私はデータ構造をいくつかのスレッドで共有する必要があります。問題は次のとおりです。 スレッドは同時に実行され、特定の構造体にデータを挿入する必要がありますが、オブジェクトはすべてmutexの除外に挿入する必要があります。再挿入してはいけません。 私は、別のスレッドが現在のスレッドの終了を待つべき同じキーを置くことを望むなら、スレッドが彼らが働いているオブジェクトのキーを置く配列を作ることを考えています。 ので、他の言葉で、すべてのスレッドがロック要素のために、この機能を実行します。この方法でC - mutexデータ構造とマルチスレッド

void unlock_element(key_t key){ 

    pthread_mutex_lock(&mtx_array); 

    while(array_busy==1){ 
    pthread_cond_wait(&var_array,&mtx_array);      
    } 

    array_busy=1; 
    zeroed((int)key);          
    array_busy=0; 
    pthread_cond_signal(&var_array); 
    pthread_mutex_unlock(&mtx_array); 
} 

:私はフォロー機能をARRYでキーを解放するオブジェクトで終了した後

void lock_element(key_t key){ 
    pthread_mutex_lock(&mtx_array); 

    while(array_busy==1){ 
    pthread_cond_wait(&var_array,&mtx_array); 
    } 
    array_busy=1; 
    if((search_insert((int)key))==-1){ 
     // the element is present in array and i can't insert, 
     // and i must wait for the array to be freed. 
     // (i think that the problem is here) 
    } 
    array_busy=0; 
    pthread_cond_signal(&var_array); 
    pthread_mutex_unlock(&mtx_array); 
} 

、結果はすべての実行で変更されます(たとえば、最初にプログラムが300オブジェクトを挿入し、2回目に100オブジェクトを挿入するなど)。

ありがとうございました!次のように私は、コードを修正

@DavidSchwartz @Asthor:UPDATE

void lock_element(key_t key){ 
    pthread_mutex_lock(&mtx_array); 
    while((search_insert((int)key))==-1){ 
     //wait 
     pthread_cond_wait(&var_array,&mtx_array); 
    } 
    pthread_mutex_unlock(&mtx_array); 
} 

と...を

void unlock_element(key_t key){ 
pthread_mutex_lock(&mtx_array); 

zeroed((int)key);         
pthread_cond_signal(&var_array); 
pthread_mutex_unlock(&mtx_array); 
    } 

しかし、動作しない...それは同じように動作します従来通り。

また、関数search_insert(key)の奇妙な動作に気付きました。

int search_insert(int key){ 
    int k=0; 
    int found=0; 
    int fre=-1; 
    while(k<7 && found==0){ 
    if(array[k]==key){ 
     found=1; 
    } else if(array[k]==-1) fre=k; 
    k++; 
    } 
    if (found==1) { 
    return -1; //we can't put the key in the array 

    }else { 
     if(fre==-1) exit(EXIT_FAILURE); 
     array[fre]=key; 
     return 0; 
    } 

    } 

は、オプションのカップルを持っている

if(found == 1) 
+1

mutexをすでに使用しているときに、なぜ 'array_busy'変数が必要でしょうか? – EOF

+0

なぜこれが下降したのですか? – arunmoezhi

+0

mutex(mtx_array)は変数array_busyをロックするためのものです。ロックされている場合にのみこの変数を使用できます。 – Flank

答えて

0

に行くことはありません。

最も単純なオプションは、操作全体でミューテックスを保持することです。より大きな並行性が必要であるという強力な証拠がない限り、このオプションを必ず選択してください。

多くの場合、複数のスレッドで作業を行うことができます。このパターンは次のようになります。

  1. ミューテックスを取得します。
  2. オブジェクトがコレクション内にあるかどうかを確認します。その場合は、コレクションのオブジェクトを使用します。
  3. それ以外の場合は、ミューテックスを解放します。
  4. オブジェクトを生成する
  5. 再度ミューテックスを取得します。
  6. オブジェクトがコレクション内にあるかどうかを確認します。そうでない場合は、追加して、生成したオブジェクトを使用します。
  7. それ以外の場合は、生成したオブジェクトを破棄して、そのオブジェクトをコレクションから使います。

この結果、2つのスレッドが同じ作業を行う場合があります。これは、不可能(一部の作業は1度しか実行できません)または同時実行性の向上が複製作業のコストに値するものではないため、ユースケースでは容認できません。

何もないが、作品の場合は、より複雑なソリューションで行くことができます:

  1. は、ミューテックスを取得します。
  2. オブジェクトがコレクション内にあるかどうかを確認します。その場合は、コレクション内のオブジェクトを使用します。
  3. 他のスレッドがオブジェクトで作業しているかどうかを確認します。そうであれば、条件変数をブロックしてステップ2に進みます。
  4. オブジェクトに対して作業していることを示します。
  5. ミューテックスを解放します。
  6. オブジェクトを生成します。
  7. ミューテックスを取得します。
  8. オブジェクトに対して作業中であることの表示を削除します。
  9. オブジェクトをコレクションに追加します。
  10. 条件変数をブロードキャストします。
  11. ミューテックスを解放します。

これは、進行中のオブジェクトを追跡するためだけの別のコレクションで実装することも、進行中であることを示す値を含む特別なバージョンのオブジェクトをコレクションに追加することもできます。

0

答えはそのままの仮定に基づいています。

このシナリオを検討してください。オブジェクトを挿入しようとするスレッドが2つあります。スレッド1とスレッド2はどちらもインデックス0のオブジェクトを取得します。次に、2つの可能なシナリオを示します。

A: スレッド1が起動し、ミューテックスを取得してオブジェクトを挿入します。スレッド1はミューテックスを再度取得しようとしますが、スレッド2はそれを持っているのでブロックされます。スレッド2はオブジェクトを挿入しようとしますが、インデックスが取られているために失敗します。したがって、挿入は起こりません。それはmutexを解放し、スレッド1はそれをつかんでインデックスを解放することができます。しかし、スレッド2はすでにオブジェクトを挿入しようとしましたが、挿入に失敗しました。つまり、合計で1つしか挿入されません。

B: 第2のシナリオ。スレッド1が起動し、ミューテックスをつかみ、オブジェクトを挿入し、ミューテックスを解放します。スレッド2がそれをつかむ前に、スレッド1は再びそれをつかみ、インデックスをクリアして再びミューテックスを解放します。スレッド2はミューテックスを取得し、ミューテックスを解放する前にオブジェクトを挿入します。このシナリオでは、2つの挿入が得られます。

最後に、スレッドがオブジェクトとスレッドの挿入に失敗したときに、if文の中に何の反応もなく、何の意味もないという問題があります。そうすれば、予想よりも挿入が少なくなります。