C 中两个进程共享内存?
我想做以下事情:
父进程创建一个子进程。然后子进程从用户那里读取 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 每次执行代码时都会更改
它永远不会浏览了子进程代码!我这样做的方式不对吗?
I want to do the following:
Parent process creates a child process. Then the child process reads n int's from the user and store them in a shared memory. The parent process then displays them.
I reached the following:
#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;
}
And the output is just this line:
Enter number<1>:
And if I entered a number, let's say 25, it outputs this:
Parent reads <r>
r: random -ve number changes every time I execute the code
It never went through the child process code ! Am I doing this in a wrong way ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
好的,最好收集答案......
您的程序存在几个问题。如果您在构建时启用警告(我使用
-Wall -Wextra
),其中很多警告将非常明显。前两个问题我已经在评论中提到过,但我在这里解释一下:
wait()
的调用。 C 或 POSIX 中没有不带参数的wait
函数。scanf
调用,您使用*++
调用它,其中*n
接受值 n 指向的内存很可能会导致崩溃。删除星号。n
)和字符串。你实际上不可能两者都做,只能选择其中之一。编辑 我想出了这个,这似乎对我有用。我对我更改的内容添加了评论。
请注意,上面列表中的第 5 点尚未解决。
Ok, better collect in an answer instead...
There are several problems with you program. If you enable warnings when building (I use
-Wall -Wextra
) a lot of them will be quite evident.The first two problems I already mentioned in my comments, but I explain them here:
wait()
. There is nowait
function in C or POSIX that takes no argument.scanf
call, you are calling it with*++
, where*n
takes the value of the memory pointed to byn
which most likely can result in a crash. Remove the asterisk.n
) and as a string. You cant really do both, pick one or the other.Edit I came up with this instead, which seems to work for me. I added comments on the things I changed.
Do note that point 5 in the list above have not been resolved.
我的问题太愚蠢了。我需要为子进程提供写入 SHM 的能力。 if 块中的这一行:
将变成这样:
感谢你们所有人,特别是@JoachimPileborg :)
My problem was so stupid. I need to provide the Child process with the ability to write into the SHM. This line in the if-block :
Will become like this:
Thanks to you all and especially to @JoachimPileborg :)
您的描述似乎不正确,因为没有输出“Parent Wrote <>”的代码。
您正在读取数字并将它们作为 int 存储在 *n++ 中,但是随后您将 '\n' 字符附加到 n-int 数组中,并且将 shm 视为字符串?
在我看来,在你的孩子身上,你正在创建一个共享内存,写入它,然后关闭(丢弃)共享内存。然后你的第二部分打开一个具有相同段的新共享内存,但它是一个新的共享内存。通常,一个进程创建共享内存,然后第二个进程打开它,当最后一个进程关闭共享内存时,操作系统会释放它。
Your description seems to not be correct since there is no code that outputs "Parent Wrote <>".
You are reading numbers and storing them as int in *n++, but then you are appending a '\n' character to the n-int array and you are treating shm as a string?
It seems to me that in your child you are creating a shared memory, writing to it and then closing (discarding) the shared memory. Then your second part opens a new shared memory with the same segment, but yet it is a new shared memory. Normally one process creates a shared memory, then the second opens it and when the last process closes the shared memory, then it is freed by the OS.
一个问题是子进程在父进程创建共享内存之前尝试使用该共享内存。父级在创建共享内存之前有一个
wait()
调用,因此当客户端尝试检索 id 时,它不会存在。即使 wait() 调用被移动,它也可能无法工作,因为存在竞争条件。对shmget
的调用可能需要在fork
调用之前进行(或者在子进程中检索它之前使用一些同步来确保它确实存在)。并且(正如其他人已经指出的那样),孩子试图将整数写入内存,而读取(打印它)则尝试将其视为字符串。
One problem is that the child process is attempting to use get the shared memory before it has been created by the parent. The parent has a
wait()
call before creating the shared memory, so it won't exist when the client tries to retrieve the id. Even if the wait() call is moved, it may not work because there is a race condition. The call toshmget
may need to precede thefork
call (or use some synchronization to make sure it actually exists before retrieving it in the child process).And (as others have already pointed out), the child is attempting to write integers to the memory while the reading (printing of it) tries to treat it as a character string.