共享内存有两个进程在C?

iTu*_*rki 4 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;
}
Run Code Online (Sandbox Code Playgroud)

输出就是这一行:

Enter number<1>:
Run Code Online (Sandbox Code Playgroud)

如果我输入一个数字,让我们说25,它会输出:

Parent reads <r>
Run Code Online (Sandbox Code Playgroud)

r:每次执行代码时随机数都会改变

它从未经历过子进程代码!我这样做是错误的吗?

Som*_*ude 11

好的,更好地收集答案而不是......

你的程序有几个问题.如果你在建造时启用警告(我使用-Wall -Wextra),很多都会很明显.

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

  1. 第一个是打电话给wait().有没有wait在C或POSIX函数,它没有参数.
  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);
         sprintf(s, "%s%d", s, n);  /* Append number to 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;
}
Run Code Online (Sandbox Code Playgroud)

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


iTu*_*rki 1

我的问题太愚蠢了。我需要为子进程提供写入 SHM 的能力。if 块中的这一行:

shmid = shmget(2009, SHMSIZE, 0);
Run Code Online (Sandbox Code Playgroud)

会变成这样:

shmid = shmget(2009, SHMSIZE, 0666 | IPC_CREAT);
Run Code Online (Sandbox Code Playgroud)

感谢你们所有人,特别是@JoachimPileborg :)