分叉后全局资源的归属

Ownership of global resources after fork

考虑一个 Foo 拥有一些资源

struct Foo
    {
    ~Foo();
    };

和全球 std::vector<Foo>。也许是愚蠢的例子,但它很好地说明了问题。

std::vector<Foo> bar;

现在,进程 forks。

如果 bar 仅由 child 进程修改,那么调用 exit 应该是在 child 进程中执行的正确操作。如果调用 _exit,bar 中的任何 Foo:s 都会泄漏。如果 parent 在分叉之前向 bar 添加了一些东西,这些 object 可能会被销毁两次。或者这可能不是问题,因为它们应该被视为不同的 objects.

处理 object 生命周期和 fork 的正确方法是什么?让 child exec 重新开始是处理这个问题的唯一理智的方法吗?

我应该注意到,在程序的这一点上,保证只有一个线程。

What is the proper way of dealing with object lifetime together with a fork?

分叉时处理共享资源的正确方法取决于这些对象或资源是什么。

对于进程内存中的任何对象或变量,您 automatically get a copy 在分叉时使用它。然后每个进程将能够修改或销毁 any 变量而不影响其他进程。这也意味着每个进程负责清理其唯一的资源副本。


对于进程外部存在的其他资源,如文件、网络套接字或共享内存;处理它们的最佳方法将取决于该资源是什么。通常,这些最佳实践将由您最初用于创建这些资源的库/API 概述。

一旦您 forked,您的变量就会表现出 copy-on-write 语义,因此子进程的任何更改都会导致子进程的唯一变量不与父进程共享。类似地,父进程中的更改将导致子进程有新的副本并且不会传播,因此父进程可以在不中断子进程的情况下达到 exit。我这样做是为了实现一个自我更新程序。

请注意,如其他答案所述,"global resources" 应根据具体情况进行处理,但变量不是全局资源。