【问题标题】:How to read from /write to anonymous shared mapping?如何从 /write 读取匿名共享映射?
【发布时间】:2015-09-27 02:13:04
【问题描述】:

尝试将消息写入与子进程的匿名共享内存,终止它。然后让家长阅读消息。我已经看到使用通过readwrite 调用获得的文件描述符映射输入和输出文件的示例。但不知道如何正确处理这个问题。

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;    
}

【问题讨论】:

  • 差不多了,你需要两件事:一个同步父级的方法,这样它在子级写入之前就不会读取,以及可以使用write 和@987654326 正常完成的实际读写@电话。阅读信号量手册:linux.die.net/man/7/sem_overview。尝试自己解决它,你就在几英寸之外(:
  • @IshayPeled 我知道我可以使用 1 作为read 的第一个参数来将消息显示到屏幕上。我认为,在这种情况下,write 需要一个文件 desc。

标签: c fork semaphore mmap


【解决方案1】:

如果您的唯一目标是在子进程和父进程之间进行读/写,那么使用管道是一种更简单的方法。它看起来像这样:

    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));
    }

【讨论】:

    【解决方案2】:

    如果您要为共享内存烦恼,那么尝试通过read()write() 调用底层文件来操作它是愚蠢的(对于匿名映射,无论如何都不存在)。如果您想通过read()write() 进行通信,那么只需创建一个管道,而无需考虑映射和共享内存。这实际上是一种完全可行的方法。

    如果您确实想为此使用共享内存,请像 memory 一样使用它。将指向共享内存区域的指针转换为适当的指向对象类型,使用普通赋值进行写入,使用普通变量/内存访问进行读取。共享内存确实会引入冲突访问和同步的潜在问题,但即使这对于您描述的简单情况也没什么大不了的:只需让父进程成功地为子进程wait()(或以其他方式通知其终止),然后再尝试读孩子写的任何东西。

    但是,您在如何设置映射方面确实存在问题:您映射 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;    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-05
      • 2012-09-06
      • 2011-10-20
      • 1970-01-01
      相关资源
      最近更新 更多