Is executing a signal handler unsignable in linux?

I have a process p registered with a signal handler for SIGALRM . The timer is set to periodically send a SIGALRM signal to process p . The process p also runs several threads. Is the signal handler unacceptable when it is started and executed? Or to say that the execution of the signal handler is not interrupted by any thread in the process p ?

PS: I thought the signal handler runs in the kernel (is this?), And the kernel does not impress user-mode threads? Correct me if this is wrong ...

+6
source share
3 answers

To a large extent - no - working with shared data in a signal handler almost always leads to a world of pain regarding flows, and also you have a mess.

By default, the signal is blocked during the operation of the signal handler (at least on linux, which may not be universal), so at least the signal handler will not be unloaded by itself. Although, if you have several threads and the signal is not blocked in other threads, the signal handler can be successfully launched simultaneously in several threads.

One thread will receive a signal and execute a handler, it will be more or less random which thread will be, although you can control it by blocking the signal in all threads that you do not want to process.

However, any of the other string of threads that processes the signal can work in parallel. The signal processing stream can start the signal processor almost anywhere in the program (until the signal is blocked). Thus, to protect this data, you need some kind of lock. The problem is that you cannot use any ordinary primitives to block threads; they are not safe for asynchronous signals. Value if you, for example. try to capture pthread_mutex_t in the signal handler, you will easily forget your program.

The only functions that you can safely call in the signal handler are those listed here . Regarding the protection of shared data, you can use sigblock () / sigunblock () as a kind of protection, ensuring that the signal handler does not start while accessing this shared data - and the signal must be blocked in all threads, otherwise it will only run in one of the streams that does not block it - descent along this road - madness.

To a large extent, the only available data that you can safely access in the signal handler is the sig_atomic_t type, in practice other types of primitive types are also safe.

What you really have to do in the signal handler is just

  • set global flag
  • check the box elsewhere when it fits, and do the action

or

  • has some kind of main loop that tracks file descriptors for events using select () / poll () or similar.
  • create a channel and control that in your main loop
  • write () bytes to the channel in the signal handler
  • run your code to process the signal, including protecting any shared data when mainloop detects an event on this channel

or

  • Keep a spare thread around
  • block this signal in all your threads
  • have this spare stream loop when calling sigsuspend () with a signal mask that delivers this signal.
  • run your code, including protecting any common signal processing data when sigsuspend () returns
+16
source

Is a signal handler, when launched and executed, un-interrupted?

No, the signal handler is proactive, like any other user level function.

I thought the signal handler is executed in the kernel (is this?)

No, the signal handler is not running in kernel mode.

The kernel checks for pending signals for the process when switching from kernel mode to user mode. If it finds a waiting signal, it sets the frame of the user stack in such a way that after returning to user mode, the process starts executing the signal handler. After that, the process starts in user mode, executing a signal handler, like any other user level function. When execution is complete, the process switches to kernel mode. Then the kernel restores the original context of the process, executed before the signal processing time.
All this mode switching is not magical. The kernel changes the corresponding return address in the user stack.

+5
source

The short answer is no.

Read the sigaction , especially the sa_mask field. By default, your stream may be interrupted by another signal, even when it is in the signal handler.

In addition, the phrase โ€œinterrupted by any thread in process pโ€ does not make sense. In general, threads execute simultaneously; they do not "interrupt" each other (except for calling pthread_kill ()).

+2
source

Source: https://habr.com/ru/post/889025/


All Articles