2017-11-10 4 views
-2

私はモニターとミューテックスでランデスを実装しようとしていますが、実際には機能しません。あなたが私にこの問題を見るのを手伝ってくれることを願っていますここでは、コードです:スレッドランデブモニター

void traitement_principal(){ 
    if(iRdv==NB_RDV){ 
     iRdv=0; 
     continuer=1; 
     pthread_cond_signal(&autoContinuer); 
    }else{ 
     continuer=0; 
    } 
    while(continuer!=1){ 
     pthread_cond_wait(&autoContinuer,&emAffichage); 
    } 
    printf("Thread %lu, je finis mon traitement mon traitement \n",pthread_self()); 
} 

void* traitement(){ 
    pthread_mutex_lock (&emAffichage);//demande accès 
    printf("Thread %lu, je commence mon traitement \n",pthread_self()); 
    iRdv+=1; 
    traitement_principal(); 
    pthread_mutex_unlock (&emAffichage);//rend accès 
    pthread_exit((void *)NULL); 
} 

void thdErreur(int codeErr, char *msgErr, void *codeArret) { 
    fprintf(stderr, "%s: %d soit %s \n", msgErr, codeErr, strerror(codeErr)); 
    pthread_exit(codeArret); 
} 

int main(int argc, char const *argv[]){ 
    int etat; 
    pthread_t idThd[NB_THREADS]; 
    for(int i = 0; i < NB_THREADS; i++){ 
     if ((etat = pthread_create(&idThd[i], NULL, traitement,NULL)) != 0) 
      thdErreur(etat, "Creation thread avec rdv",NULL); 
    } 
    for (int i = 0; i < NB_THREADS; i++) 
     if ((etat = pthread_join(idThd[i], NULL)) != 0) 
      thdErreur(etat, "Join threads afficheurs", NULL); 
    printf ("\nFin de l'execution du thread principal \n"); 
    return 0; 
} 

NB_RDV3に展開されるマクロです。

は、0に初期化されたファイルスコープ変数です。

continuerは、0に初期化されたファイルスコープ変数です。ここで

は、プログラムoputputの例である:

sample

それは私が望んでいたものではありません。例えば、最初のもののために、私が取得したいと思い

あなたのコードの中で最も重要な問題は traitement_principal()通話 pthread_cond_signal() iRdvカウンタが NB_RDVに達したときにということであるように思われる
Thread 0 I start 
Thread 1 I start 
Thread 2 I start 

Thread 0 I end 
Thread 1 I end 
Thread 2 I end 
+0

ログが英語であれば、コードを読む方がはるかに簡単です。 – Nebril

+0

開始=開始/終了=終了 – Minirock

+0

あなたが表示しているコードは不完全です。 – alk

答えて

1

。これにより、スレッドが条件変数を待っていますが、複数のスレッドを起動する必要があります。これを達成するには、代わりにpthread_cond_broadcast()に電話する必要があります。

しかし、正確にNB_RDVスレッドを確実に復帰させて処理を進めるには、さらに問題があります。 CVにブロードキャストするスレッドがミューテックスを解放した後、それを待っている他のスレッドが獲得する前に、正当なスレッドがすべてそれを再獲得することは確信できません。 traitement()で待機していたスレッドが最初に取得したスレッドの場合、そのスレッドはtraitement_principal()と入力し、continuer0にリセットしてから、ウォークスレッドが進行してから、最終的にミューテックスを再取得します。

その数はそれに達した後任意のNB_RDVのスレッドがバリアを過ぎて続行するために、それは大丈夫だ場合 - 多分番目NB_RDV後にそれを達するスレッドを含め、あなたはいくつかの変更とそれを達成することができます。 continuerをフラグとして実装するのではなく、任意の時間に値を持つカウンタにすると、待つことなくランデムを超えてさらに多くのスレッドが処理を進める可能性があります。あなたがランデブーに到着した最初のNB_RDV番目のスレッドも残して最初であることを確認する必要がある場合は、その後、私はあなたが追跡共有状態のいくつかのフォームを追加する必要があると思う一方

、その到着の順序。

+0

ありがとう、確かに、私は放送を使用した後に問題を見た。私はあなたがカウンターで言ったようにそれをしようとしますが、実際には迷惑なのは、状態が待っているスレッドが空であるかどうかを調べるための条件付き関数があったからです。しかし、私はこれに関する情報を見つけることができません。 – Minirock

+1

いいえ、@Minirock、Pthreadsには、条件変数で待機しているスレッドの数をテストする機能がありません。しかし、このようなカウンターを自分のデータ構造内の条件変数と一緒にまとめることができます。これは、おおよそあなたが行ったことです。これはここでのあなたの特定の目的に役立ちますが、思うかもしれないよりもそれほど一般的ではありません。 –

+0

私は授業で見たものとの違いが十分にあるように見えます。理論モニターのようなことは、自分自身で相互排除を実装することができるはずです...しかし実際にはCではmutexを使って実装しなければなりません...常に理論上、教師はcondtionのようなcondプロセスがモニター状態で待機しているかどうかを私に知らせる。私は次の時にそれを覚えておくべきです。 – Minirock