在多线程进程中,exec必须立即遵循fork吗?
情况: 我有一个用C编写的多线程程序。如果其中一个线程分叉,则使用exec()将子进程替换为另一个,父进程等待子进程退出 问题: 通过fork()创建子进程后,有几行代码编译要在以下exec()命令中使用的参数 假设 我假设在由fork()创建的子进程和由exec()替换的子进程之间,子进程(作为父进程的副本)将拥有父进程的所有线程,因此这些线程将运行(尽管运行时间很短),这对吗在多线程进程中,exec必须立即遵循fork吗?,c,multithreading,pthreads,exec,fork,C,Multithreading,Pthreads,Exec,Fork,情况: 我有一个用C编写的多线程程序。如果其中一个线程分叉,则使用exec()将子进程替换为另一个,父进程等待子进程退出 问题: 通过fork()创建子进程后,有几行代码编译要在以下exec()命令中使用的参数 假设 我假设在由fork()创建的子进程和由exec()替换的子进程之间,子进程(作为父进程的副本)将拥有父进程的所有线程,因此这些线程将运行(尽管运行时间很短),这对吗 如果是这样,在fork()之后立即调用exec()是正确的解决方案吗?只有调用fork的线程才会在新进程中运行。但是
如果是这样,在fork()之后立即调用exec()是正确的解决方案吗?只有调用
fork
的线程才会在新进程中运行。但是,在exec
之前可以调用的函数有一些限制。发件人:
应创建一个具有
单线程。如果是多线程
进程调用新进程fork()
应包含呼叫的副本
线程及其整个地址空间,
可能包括美国
互斥体和其他资源。
因此,为了避免错误
子进程只能执行
异步信号安全操作,直到
例如exec
函数之一的时间
被称为。叉
可以通过以下方式建立处理程序:
函数在
维持申请的命令
跨越fork()
调用的不变量
我相信这意味着,只要有多线程,您一般都会没事的
库正确使用pthread\u atfork
编辑:该页面进一步解释了库如何保护自身:
预期用途是准备
处理程序获取所有互斥锁和
其他两个fork处理程序将释放
他们
例如,应用程序可以提供
一种准备程序,用于获取
库中必要的互斥
维护和提供孩子和家长
释放互斥锁的例程,
从而确保孩子得到一份工作
系统状态的一致快照
库(并且不支持任何互斥体)
左侧搁浅)。或者,一些
图书馆也许能够提供
一个子例程,用于重新初始化
库中的互斥体以及所有
关联状态到某个已知值
(例如,当
图像最初被执行)
正如@Matthew在回答中所写的,父进程中的其他线程将不存在于子进程中(如果您使用的是PThreads)
请注意,如果不是这样,那么将exec()调用放在对fork的调用“紧跟”之后是没有帮助的,因为其他线程仍有可能在调用exec()之前运行。但是,您可以通过在调用fork()之前锁定互斥锁来控制这一点-调用exec()实际上会破坏互斥锁。我也认为,所有线程也会在子进程中复制。但事实并非如此。由于其他线程不会在子进程中复制,因此如果在exec之前使用互斥体/锁,则需要确保编写fork处理程序以正确处理它们。 这里有一篇关于它的文章。
引用的这段话表明标准库(例如,stdio、
atexit
、malloc
、线程创建和销毁等)可能在内部使用同步资源,这些资源在fork
之后可能处于不一致的状态?如果是这样,使用pthread\u atfork
如何解决问题?@R,是的,可能。这取决于图书馆。在某些情况下,它们可以在fork之前锁定所有互斥体,然后在fork之后立即释放它们。在其他情况下,可以像从头开始一样重新初始化它们。我已经添加了pthread\u atfork
中的一段相关内容。我不确定关于互斥体“基本上被破坏”的说法是否正确。正如我前面所说,锁有进入不一致状态的风险。这就是pthread\u atfork
存在的原因。