我想做以下事情:
父进程创建子进程。然后子进程从用户那里读取 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
),其中很多警告将非常明显。
前两个问题我已经在我的评论中提到了,但我在这里解释一下:
- 首先是调用
wait()
。 C 或 POSIX 中没有不带参数的wait
函数。 - 第二个问题是
scanf
调用,您使用*++
调用它,其中*n
取 值n
指向的内存,这很可能会导致崩溃。删除星号。 - 第三个问题是您将共享内存视为整数数组(使用
n
)和字符串。你真的不能两者兼顾,只能选择其中之一。 - 您在父进程中创建共享内存,但在创建内存之前等待子进程完成。
- 父进程和子进程之间存在竞争条件,因为共享内存可能是在子进程尝试访问它之后创建的。
编辑 我想出了这个,这似乎对我有用。我对更改的内容添加了评论。
#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/