如何读取/写入匿名共享映射?
How to read from /write to anonymous shared mapping?
正在尝试向子进程的匿名共享内存写入消息,终止它。然后让家长阅读消息。我已经看到使用通过 read
和 write
调用获得的文件描述符映射输入和输出文件的示例。但是不知道如何正确处理这个问题。
int main(void) {
char *shared;
int status;
pid_t child;
shared = mmap(0, sizeof(int) , PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (shared == MAP_FAILED) {
perror("mmap");
return 1;
}
child = fork();
if ( child == -1 ) {
perror("fork");
return 1;
} else if (child == 0) {
sprintf(shared, "foo");
} else {
printf("%s", shared);
wait(&status);
}
if (munmap (shared, sizeof(int)) == -1) {
perror("munmap");
return 1;
}
return 0;
}
如果您的唯一目标是在子进程和父进程之间读/写,使用管道是一种更简单的方法。它看起来像这样:
int fd[2];
pipe(fd);
if((child= fork()) == -1)
{
perror("fork");
exit(1);
}
if(child == 0)
{
// close read side
close(fd[0]);
// write to pipe
write(fd[1], msg, (strlen(msg));
}
else
{
//close write side
close(fd[1]);
//read what the child wrote.
nbytes = read(fd[0], buff, sizeof(buff));
}
如果您要为共享内存烦恼,那么尝试通过对基础文件的 read()
和 write()
调用来操纵它是愚蠢的(匿名映射不无论如何都存在)。如果您想通过 read()
和 write()
进行通信,那么只需创建一个管道,而不必考虑映射和共享内存。这实际上是一种完全可行的方法。
如果你真的想为此使用共享内存,那么像 memory 一样使用它。将指向共享内存区域的指针转换为合适的pointer-to-object类型,写入使用普通赋值,读取使用普通变量/内存访问。共享内存确实引入了访问和同步冲突的潜在问题,但对于您描述的简单情况来说,这也没什么大不了的:只需让 parent 进程成功 wait()
child(或其他方式)在它尝试读取 child 写的任何内容之前收到终止通知。
您在设置映射的方式上确实存在问题,但是:您映射 sizeof(int)
字节,但这可能不足以用于您尝试写入的消息。总的来说,它应该看起来更像这样:
int main(void) {
char *message;
int status;
pid_t child;
message = mmap(NULL, BUFSIZE , PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (message == MAP_FAILED) {
perror("mmap");
return 1;
}
child = fork();
if ( child == -1 ) {
perror("fork");
return 1;
} else if (child == 0) {
strcpy( message, "foo\n");
} else {
wait(&status);
printf("The child wrote:\n%s\n", message);
}
return 0;
}
正在尝试向子进程的匿名共享内存写入消息,终止它。然后让家长阅读消息。我已经看到使用通过 read
和 write
调用获得的文件描述符映射输入和输出文件的示例。但是不知道如何正确处理这个问题。
int main(void) {
char *shared;
int status;
pid_t child;
shared = mmap(0, sizeof(int) , PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (shared == MAP_FAILED) {
perror("mmap");
return 1;
}
child = fork();
if ( child == -1 ) {
perror("fork");
return 1;
} else if (child == 0) {
sprintf(shared, "foo");
} else {
printf("%s", shared);
wait(&status);
}
if (munmap (shared, sizeof(int)) == -1) {
perror("munmap");
return 1;
}
return 0;
}
如果您的唯一目标是在子进程和父进程之间读/写,使用管道是一种更简单的方法。它看起来像这样:
int fd[2];
pipe(fd);
if((child= fork()) == -1)
{
perror("fork");
exit(1);
}
if(child == 0)
{
// close read side
close(fd[0]);
// write to pipe
write(fd[1], msg, (strlen(msg));
}
else
{
//close write side
close(fd[1]);
//read what the child wrote.
nbytes = read(fd[0], buff, sizeof(buff));
}
如果您要为共享内存烦恼,那么尝试通过对基础文件的 read()
和 write()
调用来操纵它是愚蠢的(匿名映射不无论如何都存在)。如果您想通过 read()
和 write()
进行通信,那么只需创建一个管道,而不必考虑映射和共享内存。这实际上是一种完全可行的方法。
如果你真的想为此使用共享内存,那么像 memory 一样使用它。将指向共享内存区域的指针转换为合适的pointer-to-object类型,写入使用普通赋值,读取使用普通变量/内存访问。共享内存确实引入了访问和同步冲突的潜在问题,但对于您描述的简单情况来说,这也没什么大不了的:只需让 parent 进程成功 wait()
child(或其他方式)在它尝试读取 child 写的任何内容之前收到终止通知。
您在设置映射的方式上确实存在问题,但是:您映射 sizeof(int)
字节,但这可能不足以用于您尝试写入的消息。总的来说,它应该看起来更像这样:
int main(void) {
char *message;
int status;
pid_t child;
message = mmap(NULL, BUFSIZE , PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (message == MAP_FAILED) {
perror("mmap");
return 1;
}
child = fork();
if ( child == -1 ) {
perror("fork");
return 1;
} else if (child == 0) {
strcpy( message, "foo\n");
} else {
wait(&status);
printf("The child wrote:\n%s\n", message);
}
return 0;
}