【问题标题】:fork about parent/child process [closed]关于父/子进程的分叉[关闭]
【发布时间】:2013-01-21 05:36:38
【问题描述】:

我对C中的父/子进程有一个小问题:子进程如何访问父进程 fork之后打开的文件描述符?

【问题讨论】:

  • 你的问题有点不清楚。父进程是先打开文件再fork,还是先fork再打开文件?
  • 父进程fork然后打开文件,那么子进程如何使用这些文件呢?
  • 安东的回答是正确的。没有可移植的方法,您需要特定于操作系统的 API。

标签: c fork parent-child file-descriptor


【解决方案1】:

假设问题是关于父进程分叉然后打开新的文件描述符: 简短的回答是:不能。

有一些特定于平台的方法可以在进程之间传递文件描述符(例如,使用 unix 套接字发送的 SCM_RIGHTS 辅助消息),但它们不依赖于进程的父子关系。

【讨论】:

    【解决方案2】:

    文件描述符通过fork系统调用携带,因此子进程可以随意使用它们。这就是 IPC 与管道(参见 man 2 pipe)通常是如何完成的。

    如果您需要访问在分叉后打开的文件描述符,您可以使用sendmsg 通过 UNIX 套接字发送它们。见How to use sendmsg() to send a file-descriptor via sockets between 2 processes?

    【讨论】:

      【解决方案3】:

      在 fork() 之后,子进程获得其父文件描述符的自己的副本

      每个子文件描述符与父文件对应的文件描述符引用相同的打开文件描述。

      一旦他们拥有自己的文件描述符副本,子/父关系就无关紧要了。它与使用自己的文件描述符集访问同一文件的两个不同进程相同。之后文件锁定和同步可能会发挥作用。

      【讨论】:

        【解决方案4】:

        [已编辑-抱歉误读了问题,您不能因为进程不共享相同的内存空间。最好在 fork 之前打开文件描述符或使用其他 IPC 机制,具体取决于您要实现的目标]

        子进程会继承父进程的文件描述符,因此可以直接使用。

        void example()
        {
            int fd = open("My file", O_WRONLY );
        
            pid_t pid = fork();
            if(pid == 0)
            {
                 /* child */
                 char * child_msg = "Hi there from child\n";
                 write(fd, my_msg, sizeof(my_msg);
        
                 /* ... other stuff */
            } 
            else
            {
                /* parent */
                char * parent_msg = "Hi there from parent\n";
                write(fd, my_msg, sizeof(my_msg);
        
                /* ... other stuff */
            }
        }
        

        两条消息都将写入“我的文件”

        【讨论】:

        • 我的问题是在 fork 之后使用父级创建的文件描述符,我知道在 fork 之前打开的文件描述符是由子级继承的。
        • 抱歉误读了这个问题,你不能。
        【解决方案5】:

        你的问题不清楚。

        无论如何,如果您尝试在使用父进程的子进程中使用数据,您可以将数据从父进程传输到子进程。为简化起见,只需在 POSIX int pipe(int anFD[2]) 中使用匿名管道,然后您可以使用 writereadfreadfwrite 函数)。在父进程中,您必须使用函数popen 来打开具有写入/读取权限的文件。

        请记住,fork() 会进行完整的复制(父子共享页面,并且这些页面是只读的)。如果您尝试在源页面中写入,内核将检查子进程是否是一个所有者,然后该源页面将可写。

        【讨论】:

        • 欢迎来到 Stack Overflow。请注意,问题和答案应以半正式的英语书写,没有短信风格的缩写,例如“ur”和“u”。这次我更新了;下次你应该自己做。你也有一些问题; popen() 是一种将数据传入或传出 process 而不是 file 的机制,并且没有义务使用该函数。您必须做一些工作(可能使用fdopen())才能在管道上使用fwrite()fread()。他们使用文件流,但pipe() 返回文件描述符。
        • 父子进程确实在fork() 之后共享页面。通常,文本(代码)是只读的,但数据被标记为 COW(写时复制),因此只有在其中一个进程修改数据时才会复制它。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-29
        相关资源
        最近更新 更多