c - fork 3 个进程,使用共享内存

标签 c unix process fork

我有一项任务,我正在用头撞墙。它在 C 中。我有一种接近解决方案的感觉,但是我无法让程序执行所需的操作。我正在更改数字和一些小细节,因为大部分类(class)都和我一样难过。

要求:创建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 < 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)调用之后插入一个 wait(&status) 并且不知所措。任何指针? (没有双关语意)=)还有更多要实现,但我相信一旦我有了这部分,我就可以自己处理剩下的部分。我在某些方面故意含糊其辞,但我想完成这个项目,更重要的是理解它,还有其他人想要免费午餐。我将在代码中提供所需的任何其他内容。预先感谢您的帮助

输出应该出现

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

最佳答案

我相信 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;
} 

关于c - fork 3 个进程,使用共享内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12699966/

相关文章:

shell - 如何使用 Go 程序中的点脚本运行 graphviz 进程?

c - 当我在 GDB 中运行程序时,GDB 是如何显示程序的虚拟地址的?

c - 从 mmap-ed 内存中进行有效读取会在负载下产生 SIGBUS。为什么?

c - 如何在C套接字(sys/socket.h)中获取客户端的地址和端口?

c - 在非阻塞套接字连接中,select() 总是返回 1

php - pcntl 和 posix

C 在不同的头文件中定义具有相同名称的宏?

linux - 如何找到 pwd 中包含唯一关键字(如 "I have an important work")的所有文件?在 unix/linux 中?

bash - grep (bash) 多行模式

c - 过程 Controller 以随机顺序运行文件