2

このプロセスのグラフがあります。すべてのスレッドで、新しいプロセスが開始されます。最初はプロセス 1 で、終了するとセマフォがポストされ、次の可能性のあるプロセスは 2
4です。プロセス 1、2、または 4 は実行されません。どこに問題がありますか?

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




sem_t semA,semB,semC,semD,semE;


void* process_2 (void* param)
{ 
  sem_wait(&semA);
  int pid2, status2; 
  pid2 = fork ();
  if ( pid2 < 0 ) {
   exit(1);
  }
 if ( pid2==0 ) { 

  printf("Process 2\n");
  }
 else {
  wait(&status2);
  sem_post(&semC);
 } 
 return NULL;
}

void* process_4(void* param)
{   
 sem_wait(&semB);
 int pid4, status4;
 pid4 = fork ();
 if ( pid4 < 0 ) {
  exit(1);
 }
 if ( pid4==0 ) { 

   printf("Process 4\n");


  exit(0);
 }
 else {
  wait(&status4);
  sem_post(&semD);                          
 }


 return NULL;
}


void* process_3(void* param)
{
 sem_wait(&semC);
 int pid3, status3;
 pid3 = fork();
  if (pid3 < 0) {
  exit(0);
 }
 if (pid3 == 0) {  

   printf("Process 3\n");
 }
 else{
  wait(&status3);
  sem_post(&semE);
 }

 return NULL;

}

void* process_5(void* param)
{
 sem_wait(&semD);
 sem_wait(&semE);
 int pid5, status5;
 pid5 = fork();
 if (pid5 < 0) {
   exit(0);
 }
 if (pid5 == 0) {  
  printf("Process 5\n");
 }
 else{
  wait(&status5);
  exit(0);
 }

 return NULL;

}



int main () {

  pthread_t thread_id[4];
  pthread_create(&thread_id[0], NULL,&process_2, NULL);
  pthread_create(&thread_id[1], NULL,&process_3, NULL);
  pthread_create(&thread_id[2], NULL,&process_4, NULL);
  pthread_create(&thread_id[3], NULL,&process_5, NULL);


  sem_init(&semA,0,0); 
  sem_init(&semB,0,0);
  sem_init(&semC,0,0);
  sem_init(&semD,0,0);
  sem_init(&semE,0,0);


  int pid, status;


  pid = fork ();
  if ( pid < 0 ) {
   exit(1);
   }
  if ( pid==0 ) {  
   printf("Process 1\n");    
   }
  else { 
   wait(&status);
   sem_post(&semA);
   sem_post(&semB);
   int i;
   for (i = 0; i < 4; i++)
    pthread_join(thread_id[i],NULL);   
   return 0;
   }
 exit(0);

} 
4

2 に答える 2

3

少なくとも 1 つの問題は、セマフォを初期化する前にスレッドを生成することです。

pthread_t thread_id[4];
pthread_create(&thread_id[0], NULL,&process_2, NULL);
pthread_create(&thread_id[1], NULL,&process_3, NULL);
pthread_create(&thread_id[2], NULL,&process_4, NULL);
pthread_create(&thread_id[3], NULL,&process_5, NULL);


sem_init(&semA,0,0); 
sem_init(&semB,0,0);
sem_init(&semC,0,0);
sem_init(&semD,0,0);
sem_init(&semE,0,0);

これにより、セマフォを初期化するメイン スレッドとセマフォを使用する子スレッドとの間に競合状態が発生します。ここでは、初期化されていないデータを使用する可能性が非常に高くなります。

main() 関数で順序を入れ替えることをお勧めします。

pthread_t thread_id[4];

sem_init(&semA,0,0); 
sem_init(&semB,0,0);
sem_init(&semC,0,0);
sem_init(&semD,0,0);
sem_init(&semE,0,0);

pthread_create(&thread_id[0], NULL,&process_2, NULL);
pthread_create(&thread_id[1], NULL,&process_3, NULL);
pthread_create(&thread_id[2], NULL,&process_4, NULL);
pthread_create(&thread_id[3], NULL,&process_5, NULL);
于 2012-12-03T20:19:37.407 に答える
2

ベンの答えはあなたの主な問題を示していますが、他にも問題があります。スレッド、プロセス、およびセマフォを使用したプログラミングを非常に簡単にしています。

  • セマフォはこのようにプログラムされるべきではありません。すべてのセマフォ関数は、正当な理由でエラー リターン コードを返します。たとえばsem_wait 、プロセスがシグナルを受信すると、「偽のウェイクアップ」が発生する可能性があります。したがって、戻り値を確認してからerrno何が起こったかを確認する必要があります。POSIX セマフォをプログラミングする場合、これを回避する方法はありません。

  • セマフォは、POSIX のオプション機能にすぎません。pthread_mutex_t最初から設計された POSIX 機能、つまりとから始める方がおそらく簡単ですpthread_cond_t。補足として得られるのは携帯性です。セマフォを完全にサポートしていない非常に一般的なアーキテクチャがまだ存在します。

  • これを行う方法は、プロセス間でセマフォを共有する方法ではありません。

    親の仮想アドレス空間全体が子に複製されます

    つまり、子のセマフォはコピーであり、2 つのプロセスはそれを介して通信できません。次のようなものを使用して、プロセス共有セマフォshm_openを作成する必要があります。mmap

  • ミキシングforkとスレッドは通常、簡単な作業ではなく、実行する前によく考える必要があります。
于 2012-12-03T21:15:17.353 に答える