Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Suppose I have a parent process and a child process (started with e.g. fork() or clone()) running on Linux. Further suppose that there is some shared memory that both the parent and the child can modify.

Within the context of the parent process, I would like to stop the child process and know that it has actually stopped, and moreover that any shared memory writes made by the child are visible to the parent (including whatever synchronization or cache flushes that may require in a multi-processor system).

This answer, which speaks of using kill(SIGSTOP) to stop a child process, contains an interesting tidbit:

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

Is this statement actually true, and if so, can anyone expound on it, or point me to some more detailed documentation (e.g. a Linux manpage)? Otherwise, is there another mechanism that I can use to ensure that the child process is completely stopped and is not going to be doing any more writes to the shared memory?

I'm imagining something along the lines of:

  1. the parent sends a different signal (e.g. SIGUSR1), which the child can handle
  2. the child handles the SIGUSR1 and does something like a pthread_cond_wait() in the signal handler to safely "stop" (though still running from the kernel perspective) -- this is not fully fleshed out in my mind yet, just an idea

I'd like to avoid reinventing the wheel if there's already an established solution to this problem. Note that the child process needs to be stopped preemptively; adding some kind of active polling to the child process is not an option in this case.

If it only existed on Linux, pthread_suspend() would be perfect ...

like image 738
John Lindgren Avatar asked Oct 20 '25 01:10

John Lindgren


1 Answers

It definitely sounds like you should be using a custom signal with a handler, and not sigstop.

It's rare not to care about the state of the child at all, e.g. being fine with it having stored 32bits out of a single non-atomic 64bit write, or logically caught between two dependent writes.

Even if you are, POSIX allows the OS to not make shared writes immediately visible to other processes, so the child should have a chance to call msync for portability, to ensure that writes are completely synced.

like image 63
that other guy Avatar answered Oct 22 '25 05:10

that other guy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!