kill(SIGSTOP) 是否在 kill() returns 时生效?

Does kill(SIGSTOP) take effect by the time kill() returns?

假设我在 Linux 上有一个 parent 进程和一个 child 进程(从例如 fork() 或 clone() 开始)运行。进一步假设 parent 和 child 都可以修改一些共享内存。

在 parent 进程的上下文中,我想停止 child 进程并且知道它实际上已经停止,而且 [=37] 进行的任何共享内存写入=] 对 parent 可见(包括 multi-processor 系统中可能需要的任何同步或缓存刷新)。

,谈到使用 kill(SIGSTOP) 停止 child 进程,包含一个有趣的花絮:

When the first kill() call succeeds, you can safely assume that the child has stopped.

这个说法真的正确吗?如果是这样,谁能解释一下,或者给我指点一些更详细的文档(例如 Linux 联机帮助页)?否则,我是否可以使用另一种机制来确保 child 进程完全停止并且不会再对共享内存进行任何写入?

我正在想象一些类似的东西:

  1. parent 发送不同的信号(例如 SIGUSR1),child 可以处理
  2. child 处理 SIGUSR1 并在信号处理程序中执行类似 pthread_cond_wait() 的操作以安全地 "stop" (尽管从内核角度来看仍然 运行 ) -- 这在我脑海中还没有完全充实,只是一个想法

如果这个问题已经有了既定的解决方案,我想避免重新发明轮子。注意child进程需要抢先停止;在这种情况下,向 child 进程添加某种主动轮询不是一种选择。

如果它只存在于 Linux,pthread_suspend() 将是完美的...

听起来您应该使用带有处理程序的自定义信号,而不是 sigstop。

很少有人完全不关心 child 的状态,例如它可以从单个 non-atomic 64 位写入中存储 32 位,或者在逻辑上夹在两个相关写入之间。

即使你是,POSIX 也允许 OS 不让共享写入立即对其他进程可见,因此 child 应该有机会调用 msync 为了便携性,确保写入完全同步。

POSIX documentation on Signal Concepts 强烈建议,但没有明确说明目标进程将在 kill() 之前停止 returns:

A signal is said to be "generated" for (or sent to) a process or thread when the event that causes the signal first occurs... Examples of such events include ... invocations of the kill() and sigqueue() functions.

文档很难区分信号 generationdelivery(当信号动作生效时)或 接受。不幸的是,它有时会提到在生成时响应停止信号而采取的行动,有时在交付时。鉴于 某些事情 必须在生成 本身 时发生,我同意目标进程必须在您调用时停止 returns.

但是,以另一个系统调用为代价,您可以确定。由于您在设计中有一个 parent/child 关系,您可以 waitpid()/WUNTRACED 收到您的子进程确实已停止的通知。

编辑

查看其他 from that other guy [原文如此],了解您可能 不想 想要这样做的原因。