分叉后全局资源的归属
Ownership of global resources after fork
考虑一个 Foo
拥有一些资源
struct Foo
{
~Foo();
};
和全球 std::vector<Foo>
。也许是愚蠢的例子,但它很好地说明了问题。
std::vector<Foo> bar;
现在,进程 fork
s。
如果 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 概述。
一旦您 fork
ed,您的变量就会表现出 copy-on-write 语义,因此子进程的任何更改都会导致子进程的唯一变量不与父进程共享。类似地,父进程中的更改将导致子进程有新的副本并且不会传播,因此父进程可以在不中断子进程的情况下达到 exit
。我这样做是为了实现一个自我更新程序。
请注意,如其他答案所述,"global resources" 应根据具体情况进行处理,但变量不是全局资源。
考虑一个 Foo
拥有一些资源
struct Foo
{
~Foo();
};
和全球 std::vector<Foo>
。也许是愚蠢的例子,但它很好地说明了问题。
std::vector<Foo> bar;
现在,进程 fork
s。
如果 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 概述。
一旦您 fork
ed,您的变量就会表现出 copy-on-write 语义,因此子进程的任何更改都会导致子进程的唯一变量不与父进程共享。类似地,父进程中的更改将导致子进程有新的副本并且不会传播,因此父进程可以在不中断子进程的情况下达到 exit
。我这样做是为了实现一个自我更新程序。
请注意,如其他答案所述,"global resources" 应根据具体情况进行处理,但变量不是全局资源。