c - C 中两个进程共享内存?

标签 c fork shared-memory

我想做以下事情:

父进程创建子进程。然后子进程从用户那里读取 n 个 int 并将它们存储在共享内存中。然后父进程显示它们。

我达到了以下目标:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#define SHMSIZE 27
int main() {
   int shmid;
   int *shm;
   int *n;

   if(fork() == 0) {
      shmid = shmget(2009, SHMSIZE, 0);
      shm = shmat(shmid, 0, 0);
      n = shm;
      int i;
      for(i=0; i<5; i++) {
         printf("Enter number<%i>: ", i);
         scanf("%d", n++);
      }
      printf ("Child wrote <%d>\n",shm);
      shmdt(shm);
   }
   else {
      wait();
      int *s;
      shmid = shmget(2009, SHMSIZE, 0666 | IPC_CREAT);
      shm = shmat(shmid, 0, 0);
      s = shm;
      wait(NULL);
      printf ("Parent reads <%d>\n",shm) ;
      shmdt(shm);
      shmctl(shmid, IPC_RMID, NULL);
   }
   return 0;
}

输出就是这一行:

Enter number<1>:

如果我输入一个数字,比如 25,它会输出:

Parent reads <r>

r: random -ve number changes per time I execute the code

它从未经过子进程代码!我这样做的方式不对吗?

最佳答案

好吧,最好收集一个答案......

你的程序有几个问题。如果您在构建时启用警告(我使用 -Wall -Wextra),其中很多警告将非常明显。

前两个问题我已经在我的评论中提到了,但我在这里解释一下:

  1. 首先是调用wait()。 C 或 POSIX 中没有不带参数的 wait 函数。
  2. 第二个问题是 scanf 调用,您使用 *++ 调用它,其中 *n n 指向的内存,这很可能会导致崩溃。删除星号。
  3. 第三个问题是您将共享内存视为整数数组(使用n)和字符串。你真的不能两者兼顾,只能选择其中之一。
  4. 您在父进程中创建共享内存,但在创建内存之前等待子进程完成。
  5. 父进程和子进程之间存在竞争条件,因为共享内存可能是在子进程尝试访问它之后创建的。

编辑 我想出了这个,这似乎对我有用。我对更改的内容添加了评论。

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <sys/wait.h>  /* Needed for the wait function */
#include <unistd.h>    /* needed for the fork function */
#include <string.h>    /* needed for the strcat function */
#define SHMSIZE 27
int main() {
   int shmid;
   char *shm;

   if(fork() == 0) {
      shmid = shmget(2009, SHMSIZE, 0);
      shm = shmat(shmid, 0, 0);
      char *s = (char *) shm;
      *s = '\0';  /* Set first location to string terminator, for later append */
      int i;
      for(i=0; i<5; i++) {
         int n;  /* Variable to get the number into */
         printf("Enter number<%i>: ", i);
         scanf("%d", &n);

         char number[20];
         sprintf(number, "%d", n);  /* Convert the number to string */
         strcat(s, number);  /* Append the number to the string */
      }
      strcat(s, "\n");  /* Append newline */
      printf ("Child wrote <%s>\n",shm);
      shmdt(shm);
   }
   else {
      /* Variable s removed, it wasn't used */
      /* Removed first call to wait as it held up parent process */
      shmid = shmget(2009, SHMSIZE, 0666 | IPC_CREAT);
      shm = shmat(shmid, 0, 0);
      wait(NULL);
      printf ("Parent reads <%s>\n",shm) ;
      shmdt(shm);
      shmctl(shmid, IPC_RMID, NULL);
   }
   return 0;
}

请注意,上面列表中的第 5 点尚未解决。

关于c - C 中两个进程共享内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8186953/

相关文章:

c# - 从 C# 将数据传入和传出 DLL

c - 如何将指针数组转换为字符数组?

创建一个带有内置静态库的exe文件

c - 在c程序中确定以太网帧到达时间的最准确方法

java - 如何从我从 `java` 目标派生的 Ant 任务中停止 Selenium 服务器?

python - 在多处理进程之间将opencv视频帧共享为Numpy数组的正确方法

c++ - 将共享内存指针类型转换为整数指针

c++ - 在 C++ 中创建多个进程并与管道通信

linux - 在 fork 期间, child 的执行究竟从哪里开始?

c - 共享内存中数组的长度是多少?