【问题标题】:Implementing pipe using shared memory使用共享内存实现管道
【发布时间】:2013-01-18 13:47:38
【问题描述】:

我正在使用共享内存实现管道。 我应该只写和触摸图书馆,而不是main()

我遇到了一个问题:

假设这是某个使用我的库shared_memory_pipe.h 的用户的main()

#include "shared_memory_pipe.h"

int main() {
    int fd[2];
    shared_memory_pipe(fd);
    if (fork()) {
        while(1) {}
    }
    shared_memory_close(fd[0]);
    shared_memory_close(fd[1]);
}

在这个例子中,我们看到孩子关闭了他的两个 fd,但父亲陷入了无限循环,并且永远不会关闭他的 fd。在这种情况下,我的管道应该仍然存在(与所有写入 fd 已关闭、所有读取 fd 已关闭或全部已关闭的情况相比,因此管道应该死掉)。

正如我之前所说,我只编写库 (shared_memory_pipe.h)。 那么,在图书馆内部,我怎么知道fork() 是否已经生成?

我怎么知道有另一个进程对我的共享内存管道有读/写端,所以我会知道关闭/不关闭我的共享内存管道?

我听说有一个命令知道有 fork() 或类似的东西,但我没有找到它,我也不知道。

先谢谢了! 如果您需要更多信息,请询问。

【问题讨论】:

    标签: c shared-libraries pipe shared-memory


    【解决方案1】:

    在任何分叉之前,父级可以将getpid() 的结果存储到全局pid_t pid_parent

    在稍后的时间点,该进程不能再次使用getpid()pid_parent 进行测试。

    如果getpid() 的结果与pid_parent 不同,则该进程距父进程至少有一个fork()。

    【讨论】:

    • 我不明白,我不写main(),我不能在那里做。如果我在图书馆这样做,那么在某些情况下孩子可能永远不会使用图书馆的任何功能,所以我永远无法知道他的 pid
    【解决方案2】:

    代码的哪一部分负责关闭fd?

    如果是用户的代码,那么fork() 不是您的问题。毕竟,调用者可以对不同的程序执行execve(匿名管道的常见用法),因此您的库代码现在从进程中消失了,即使 fd 仍然打开,所以您无法处理那个。

    如果您有用于关闭 FD 的库 API,那么您可以做的就是这些。一个已执行的程序无论如何都不会调用您的库。

    【讨论】:

    • 我刚刚编辑了我的问题,因为我没有写正确的close()main() 应该像真正的管道一样关闭共享内存管道,在pipe(fd) 之后,你应该这样做close(fd[0]), close(fd1[1])
    • @hudac:好的,所以如果关闭 fd 是 main 的责任,而不是图书馆,那么当他们没有正确关闭 fd 时,你的责任是什么?例如,他们可以关闭一个 fd 而不是另一个。
    • 没错,用户可以为所欲为……问题是:如何跟踪打开的fd?例如,我怎么知道所有进程是否都关闭了特定 fd 的写入端?因为如果所有进程都关闭了特定fd的写入端,那么作为普通管道,我应该删除管道,不是吗?
    • 在 fd 打开时管道将保持打开状态。无论如何,您不能专门删除匿名管道。但是我很困惑,“普通管道”是什么意思,什么是“共享内存管道”。你是在使用shmget 等,还是在使用fifo?
    • 我不能删除匿名管道,但是如果我close()在每个进程中写入fd,那么管道将被删除。 “普通管道”是指pipe(fd),而“共享内存管道”是我实现的具有共享内存的管道(shmget 等...)
    猜你喜欢
    • 2013-01-27
    • 1970-01-01
    • 1970-01-01
    • 2012-03-30
    • 1970-01-01
    • 2011-06-02
    • 2014-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多