1

I need to run a cleanup before exiting service upon termination (by Linux systemctl stop my-srv

I came up so far with 2 solutions:

void signal_callback(int code)
{
    _exit(0);
}

. . .
void main.. {
   signal(SIGTERM, signal_callback)
   fgetc(stdin); // wait for signal
}

on what thread the signal_callback is called? will it be the same thread which registered the callback? I mean if I call signal on main thread and then call exit in the signal_callback - will the application terminate gracefully?

Boppity Bop
  • 9,613
  • 13
  • 72
  • 151
  • If signals are implemented with exceptions then there's no threading involved. – Michael Chourdakis Apr 13 '22 at 13:47
  • sorry it doesnt mean anything to me - "implemented with exceptions". can you explain pls? – Boppity Bop Apr 13 '22 at 13:48
  • 2
    see [Execution of signal handlers](https://man7.org/linux/man-pages/man7/signal.7.html) – Alan Birtles Apr 13 '22 at 13:52
  • apparently simple `pause` will do.. weird how nobody said that although id been asking for days.. – Boppity Bop Apr 13 '22 at 14:01
  • 1
    Note that `exit` is not signal-safe. Only the functions listed in [signal-safety(7)](https://man7.org/linux/man-pages/man7/signal-safety.7.html) are safe to call from a signal handler (at least, without taking very specific precautions, which are mentioned in that man page), and `exit` is not among them (`_exit` is though). – Miles Budnek Apr 13 '22 at 14:04
  • Does this answer your question? [Signal handling with multiple threads in Linux](https://stackoverflow.com/questions/11679568/signal-handling-with-multiple-threads-in-linux) – Jean-Baptiste Yunès Apr 13 '22 at 15:06

2 Answers2

4

on what thread the signal_callback is called?

Depends on how you send the signal.

  • If you send a signal using raise, then the callback will be called in the same thread.
  • If you send a signal using pthread_kill, then the signal callback will be called in the thread that whose id was passed to pthread_kill.
  • If you send a signal using kill then I think it's best to quote documentation:

    POSIX.1 requires that if a process sends a signal to itself, and the sending thread does not have the signal blocked, and no other thread has it unblocked or is waiting for it in sigwait(3), at least one unblocked signal must be delivered to the sending thread before the kill() returns.

There will be differences if

if I ... call exit in the signal_callback - will the application terminate gracefully?

No, exit is not an async safe function. It's not OK to call it from a signal handler.

Regarding edit: _exit is async safe so you may call it. But it won't call registered cleanup functions, nor would the stack be unwound, so I wouldn't describe it as "graceful" as such.


P.S. main must return int.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • youd rather write 5 pages explanation why not rather than 2 lines of code showing how it should work.. i get it. – Boppity Bop Apr 13 '22 at 14:19
  • 3
    @BoppityBop You already wrote the code. I explained what your code would do. How would writing 2 lines of code explain what your code does? – eerorika Apr 13 '22 at 14:21
1

By default, signals are sent to the process; not to any specific threads that process may have. If there are multiple threadss, which thread handles signal(s) isn't specified by standards.

You can of course mask the signals so that certain threads don't receive them or that only a specific thread handles the signals. See pthread_sigmask for Linux.

if I call signal on main thread and then call exit in the signal_callback - will the application terminate gracefully?

What "gracefully" means depends on your program. If you setup a signal handler as you have, it'd simply exit upon receiving the signal. Whether that the process dies cleanly depends on what it was doing when it received signal such as whether any cleanup action is needed, resources need to be released (the ones not released automatically upon exit), etc.

P.P
  • 117,907
  • 20
  • 175
  • 238