代码之家  ›  专栏  ›  技术社区  ›  SlappyTheFish

在多线程进程中,exec是否必须立即跟踪fork?

  •  10
  • SlappyTheFish  · 技术社区  · 15 年前

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

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

    假设 假设在fork()创建的子进程与exec()替换的子进程之间的时间内,子进程(父进程的副本)将拥有父进程的所有线程,因此这些线程将运行(尽管运行时间很短),这是正确的吗?

    如果是,那么在fork()之后立即调用exec()的正确解决方案是什么?

    3 回复  |  直到 15 年前
        1
  •  10
  •   Matthew Flaschen    15 年前

    只有调用的线程 fork 将在新进程中运行。但是,以前可以调用哪些函数是有限制的 exec . 从 fork :

    应使用 单线程。如果一个多线程 处理呼叫 fork() 新工艺 应包含呼叫的副本 线程及其整个地址空间, 可能包括 互斥体和其他资源。 因此,为了避免错误, 子进程只能执行 异步信号安全操作直到 像这样的时间 执行程序 功能 被调用。叉子 可以通过以下方式建立处理程序 的 pthread_atfork() 功能 维护应用程序的命令 不变量交叉 Frk() 电话。

    我相信这意味着你通常应该没事,只要有多线程 库使用 pthread_atfork 正确。

    编辑:The pthread_atfork page进一步解释了库如何保护自身:

    预期用途是 处理程序获取所有互斥锁和 另外两个拨叉处理器释放 他们。

    例如,应用程序可以提供 获取 必要的静音库 维护和提供子级和父级 释放这些互斥体的例程, 从而确保孩子获得 状态的一致快照 库(没有互斥体 左侧搁浅)。或者,一些 图书馆也许可以提供 重新初始化 库中的互斥体 关联状态到某个已知值 (例如,当 图像最初执行)。

        2
  •  3
  •   Avi    15 年前

    正如@matthew在其答案中所写,父进程中的其他线程将不存在于子进程中(如果您使用pthreads)。

    请注意,如果不是这样,则将exec()调用置于对fork的调用“紧接其后”是没有帮助的,因为其他线程仍有可能在对exec()的调用之前运行。但是,您可以通过在调用fork()之前锁定互斥体来控制这一点——它基本上会被对exec()的调用破坏。

        3
  •  0
  •   cexpert    15 年前

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