C - 在多线程进程中 exec 是否必须立即跟随 fork ?

发布于 2024-10-03 03:51:18 字数 336 浏览 5 评论 0原文

情况: 我有一个用 C 编写的多线程程序。如果其中一个线程分叉,则使用 exec() 将子进程替换为另一个线程,并且父进程等待子进程退出。

问题: 通过 fork() 创建子进程后,有几行代码编译要在以下 exec() 命令中使用的参数。

假设 我是否正确地假设在 fork() 创建子进程和被 exec() 替换子进程之间的时间里,子进程(作为父进程的副本)将拥有父进程的所有线程,因此这些线程会运行——尽管持续时间很短?

如果是这样,在 fork() 之后立即调用 exec() 是正确的解决方案吗?

Situation:
I have a multithreaded program written in C. If one of the threads forks, the child process is replaced by another using exec() and the parent waits for the child to exit.

Problem:
After the child process is created by fork() there are a few lines of code that compile the arguments to be used in the following exec() command.

Hypothesis
Am I correct in assuming that in the time between the child process being created by fork() and being replaced by exec(), the child process - being a copy of the parent - will have all the threads of the parent and therefore these threads will run - albeit for a very brief period?

If so, is the correct solution to call exec() immediately after fork()?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

﹂绝世的画 2024-10-10 03:51:18

只有调用fork的线程才会在新进程中运行。但是,在 exec 之前可以调用的函数是有限制的。来自 fork

应创建一个进程
单线程。如果是多线程
进程调用fork(),新进程
应包含调用的副本
线程及其整个地址空间,
可能包括以下州
互斥体和其他资源。
因此,为了避免错误,
子进程只能执行
异步信号安全操作直到
例如 exec 函数之一
被称为。叉
处理程序可以通过以下方式建立
pthread_atfork() 函数的
为了维持申请
fork() 调用之间的不变量。

我相信这意味着你通常应该没问题,只要任何多线程
库正确使用pthread_atfork

编辑: pthread_atfork 页面进一步解释了如何图书馆可以保护自己:

预期的用途是准备
处理程序获取所有互斥锁并且
另外两个叉车释放
他们。

例如,应用程序可以提供
一个准备例程,获取
库中必要的互斥体
维持和供应孩子和父母
释放这些互斥体的例程,
从而确保孩子获得
状态的一致快照
库(并且没有互斥体)
搁浅)。或者,一些
图书馆也许只能提供
重新初始化的子例程
库中的互斥体和所有
将状态与某个已知值相关联
(例如,当
图像最初是执行的)。

Only the thread that calls fork will be running in the new process. However, there are limits to which functions you can call before exec. From fork:

A process shall be created with a
single thread. If a multi-threaded
process calls fork(), the new process
shall contain a replica of the calling
thread and its entire address space,
possibly including the states of
mutexes and other resources.
Consequently, to avoid errors, the
child process may only execute
async-signal-safe operations until
such time as one of the exec functions
is called. Fork
handlers may be established by means
of the pthread_atfork() function in
order to maintain application
invariants across fork() calls.

I believe this means you should generally be okay, as long as any multi-threaded
libraries use pthread_atfork properly.

EDIT: The pthread_atfork page explains further how the library can protect itself:

The expected usage is that the prepare
handler acquires all mutex locks and
the other two fork handlers release
them.

For example, an application can supply
a prepare routine that acquires the
necessary mutexes the library
maintains and supply child and parent
routines that release those mutexes,
thus ensuring that the child gets a
consistent snapshot of the state of
the library (and that no mutexes are
left stranded). Alternatively, some
libraries might be able to supply just
a child routine that reinitializes the
mutexes in the library and all
associated states to some known value
(for example, what it was when the
image was originally executed).

和我恋爱吧 2024-10-10 03:51:18

正如 @Matthew 在他的回答中所写,父进程中的其他线程将不会存在于子进程中(如果您使用的是 PThreads)。

请注意,如果不是这样,那么将 exec() 调用“紧接在”fork 调用之后是无济于事的,因为其他线程仍然有可能在调用 exec() 之前运行。但是,您可以通过在调用 fork() 之前锁定互斥体来控制这一点 - 它实际上会被调用 exec() 破坏。

As @Matthew wrote in his answer, the other threads from the parent process will not exist in the child process (if you are using PThreads).

Note that if this were not so, it wouldn't help to place the exec() call "immediately after" the call to fork, since there would still be the possibility that the other threads would run before the call to exec(). You could, however, control this by locking a mutex before calling fork() - it would essentially get destroyed by the call to exec().

撧情箌佬 2024-10-10 03:51:18

我也认为,所有线程也将在子进程中复制。但事实并非如此。由于其他线程不会在子进程中复制,因此如果您在 exec 之前使用互斥体/锁,则需要确保编写 fork 处理程序以正确处理它们。
这是一篇关于它的文章。
http://learnwithtechies.com/tech/index.php?option=com_content&view=article&id=15:fork-in-multithreaded-environment&catid=10:unix

I too thought , all the threads will be replicated in the child process too. But thats not true. Since other threads are not replicated in the child process, if you are using mutexes/locks before exec, you need to make sure that fork handlers are written to handle them properly.
Here is an article on it.
http://learnwithtechies.com/tech/index.php?option=com_content&view=article&id=15:fork-in-multithreaded-environment&catid=10:unix

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文