使用共享内存分叉3个进程

时间:2012-10-02 23:34:07

标签: c unix process fork

我有一项任务,我的头靠在墙上。它在C中。我有一种感觉即将接近解决方案,但是我无法让程序完成所需的操作。我正在更改数字和一些小细节,因为大多数课程都和我一样难过。

要求:创建3个进程,第一个将共享内存变量“total-> value”从1增加到10000,第二个从10000增加到12000,第三个从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);
}

第二个是k&lt; 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");
   }
}

在第二次开始之前,我需要的是第一个完成的过程。我尝试在process1()(或2或3)调用之后插入等待(&amp; status)并且不知所措。有什么指针吗? (没有双关语意)=)还有更多要实现,但我相信一旦我有了这部分,我可以自己处理剩下的部分。我在某些方面有意模糊,但我想完成这个项目,更重要的是要了解它,还有其他人想要免费的午餐。我将在代码中提供所需的任何其他内容。提前感谢您的帮助

输出应该出现

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

1 个答案:

答案 0 :(得分:0)

我相信Celada对要求的评论/猜测是正确的。但是,除非这样做,并且冒着做太多工作的风险,否则以下代码符合您的规范。使用内置的__sync_fetch_and_add() gcc可能是不必要的。

#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;
}