2

私には課題があり、頭を壁にぶつけています。それはCです。私は解決策に近づいていると感じていますが、プログラムに必要なことをさせることはできません。クラスのほとんどが私と同じように困惑しているので、数字といくつかの小さな詳細を変更しています.

要件: 3 つのプロセスを作成します。最初のプロセスは共有メモリ変数 "total->value" を 1 から 10000 に増やし、2 つ目は 10000 から 12000 に増やし、3 つ目は 12000 から 14000 に増やします。

プロセス関数には (process1()、process2()、process3()) などのラベルが付けられ、これらの関数の内部は次のようになります。

process1()
{
   int k = 0;
   while (k < 10000)
   {
      k++;
      total->value = total->value + 1;
   }
   printf("From process 1 = %d/n", total->value);
}

2 番目は k < 2000 (共有値をさらに 2000 だけインクリメントする必要があるため) などです。

プログラムの主要部分は次のとおりです。

main()
{
   int shmid;
   int pid1;
   int pid2;
   int pid3;
   int ID;
   int status;
   char *shmadd = (char *)0;

   /* Create and connect to a shared memory segmentt */
   if ((shmid = shmget(SHMKEY, sizeof (int), IPC_CREAT | 0666)) < 0)
   {
      perror("shmget");
      exit(1);
   }

   if ((total = (shared_mem *)shmat(shmid, shmadd, 0)) == (shared_mem *)-1)
   {
      perror("shmat");
      exit(0);
   }

   total->value = 0;

   if ((pid1 = fork()) == 0)
      process1();

   if ((pid1 != 0) && (pid2 = fork()) == 0)
      process2();

   if ((pid1 != 0) && (pid2 != 0) && (pid3 = fork()) == 0)
      process3();

   if ((pid1 != 0) && (pid2 != 0) && (pid3 != 0))
   {
      if ((shmctl(shmid, IPC_RMID, (struct shmid_ds *)0)) == -1)
      {
         perror("shmctl");
         exit(-1);
      }
      printf("\t\t  End of Program.\n");
   }
}

私が必要とするのは、2番目のプロセスが開始する前に、最初のプロセスが終了することです。process1() (または 2 または 3) 呼び出しの後に wait(&status) を挿入しようとしましたが、途方に暮れています。ポインタはありますか?(しゃれは意図されていません) =) 実装することはまだありますが、この部分があれば、残りは自分で処理できると思います。私はいくつかの点で意図的に曖昧にしていますが、私はこのプロジェクトを終了し、さらに重要なことにそれを理解したいと思っています. 必要なコードで他に何かを提供します。よろしくお願いいたします。

出力が表示されるはずです

From process 1 = 10000  
From process 2 = 12000  
From process 3 = 14000  
4

1 に答える 1

0

要件に関するCeladaのコメント/推測は正しいと思います。ただし、それを除けば、多くの作業を行うリスクがあるため、次のコードは仕様を満たしています。gccビルトインの使用__sync_fetch_and_add()はおそらく不要です。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/wait.h>

static struct {
   int value;
} *total;

static void process1(void) { 
   int k = 0;  
   while (k < 10000) {  
      k++;  
      __sync_fetch_and_add(&total->value, 1);  
    }  
    printf("From process 1 = %d\n", total->value); //<-- not quite right: could be >10000
}

static void process2(void) { 
   int k = 0;
   while (__sync_fetch_and_add(&total->value, 0) != 10000)
      ;
   while (k < 2000) {  
      k++;  
      __sync_fetch_and_add(&total->value, 1);  
   }  
   printf("From process 2 = %d\n", total->value);
}

static void process3(void) { 
   int k = 0;  
   while (__sync_fetch_and_add(&total->value, 0) != 12000)
      ;
   while (k < 2000) {  
      k++;  
      __sync_fetch_and_add(&total->value, 1);  
    }  
    printf("From process 3 = %d\n", total->value);
}

int main(void) {
   int   shmid;
   int   pid1;
   int   pid2;
   int   pid3;
   int   status;

   /* Create and connect to a shared memory segment */
   if ((shmid = shmget(1234, sizeof *total, IPC_CREAT|0666)) < 0) {
      perror ("shmget");
      exit (1);
   }
   if ((total = shmat(shmid, 0, 0)) == (void *)-1) {
      perror("shmat");
      exit (0);
   }
   total->value = 0; // not necessary in Linux if IPC_CREAT invoked

   if (!(pid1 = fork()))
      process1();
   else if (!(pid2 = fork()))
      process2();
   else if (!(pid3 = fork()))
      process3();
   else {
      wait(&status);
      wait(&status);
      wait(&status);
      if ((shmctl(shmid, IPC_RMID, (struct shmid_ds *) 0)) == -1) {
         perror("shmctl");
         exit (-1);
      }
      printf("\t\t  End of Program.\n");
   }
   return 0;
} 
于 2012-10-03T01:08:42.917 に答える