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

我想做以下事情:

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

我达到了以下目的:

#include  #include  #include  #include  #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); scanf("%d", n++); } printf ("Child wrote \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 \n",shm) ; shmdt(shm); shmctl(shmid, IPC_RMID, NULL); } return 0; } 

输出只是这一行:

 Enter number: 

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

 Parent reads  

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

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

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

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

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

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

编辑我想出了这个,这似乎对我有用。 我对我改变的事情添加了评论。

 #include  #include  #include  #include  #include  /* Needed for the wait function */ #include  /* needed for the fork function */ #include  /* 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; } 

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

您的描述似乎不正确,因为没有输出“Parent Wrote <>”的代码。

你正在读取数字并将它们作为int存储在* n ++中,但是你在n-int数组中附加一个’\ n’字符并且你将shm视为一个字符串?

在我看来,在你的孩子中,你正在创建一个共享内存,写入它然后关闭(丢弃)共享内存。 然后你的第二部分打开一个具有相同段的新共享内存,但它是一个新的共享内存。 通常,一个进程创建一个共享内存,然后第二个进程打开它,当最后一个进程关闭共享内存时,它将被操作系统释放。

一个问题是子进程在父进程创建之前尝试使用获取共享内存。 父进程在创建共享内存之前有一个wait()调用,因此当客户端尝试检索id时它不存在。 即使移动了wait()调用,它也可能无效,因为存在竞争条件。 对shmget的调用可能需要在fork调用之前(或者在子进程中检索它之前使用某些同步来确保它实际存在)。

并且(正如其他人已经指出的那样),孩子试图将整数写入内存,而阅读(打印它)则试图将其视为字符串。

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

 shmid = shmget(2009, SHMSIZE, 0); 

会变成这样:

 shmid = shmget(2009, SHMSIZE, 0666 | IPC_CREAT); 

非常感谢大家,尤其感谢@JoachimPileborg 🙂