I am new to python. I want to understand how python execute signal .I started reading the official documentation. The following statements doesn't make sense
1.Python signal handler does not get executed inside the low-level (C) signal handler. Instead, the low-level signal handler sets a flag which tells the virtual machine to execute the corresponding Python signal handler at a later point(for example at the next bytecode instruction).
2."Python signal handlers are always executed in the main Python thread of the main interpreter, even if the signal was received in another thread."
Can someone help me
When you are registering signal handlers, you primarily are opting for asynchronous handling of the signals. When the signal is received, the code execution jumps to those registered signal handlers (There are exceptions check sigaction). You can't do much in the signal handlers, and it is safe only to call async-signal-safe functions.
Python doesn't immediately jump to the signal handler (registered by the user) when the signal is received, and it instead jumps to the low-level C signal handler where it just queues what to execute later (Refer to this answer)
As each process has its own signal queue, each thread in the process has its own signal queue. But the thread signal queue is the union of its own queue and the process queue; that is how POSIX threads are modeled. And this feature is exploited for inter-thread communication (achieved using pthread_sigmask and sigwait). But that is not the case with python. Python signal handlers are always executed in the main interpreter's main python thread, and only the main thread of the main interpreter is allowed to set a new signal handler.
Related
My application is sometimes terminating from SIGIO or SIGUSR1 signals even though I have blocked these signals.
My main thread starts off with blocking SIGIO and SIGUSR1, then makes 2 AIO read operations. These operations use threads to get notification about operation status. The notify functions (invoked as detached threads) start another AIO operation (they manipulate the data that has been read and start writing it back to the file) and notification is handled by sending signal (one operation uses SIGIO, the other uses SIGUSR1) to this process. I am receiving these signals synchronously by calling sigwait in the main thread. Unfortunately, sometimes my program crashes, being stopped by SIGUSR1 or SIGIO signal (which should be blocked by a sigmask).
One possible solution is to set SIG_IGN handlers for them but this doesn't solve the problem. Their handlers shouldn't be invoked, rather should they be retrieved from pending signals by sigwait in the next iteration of the main program loop.
I have no idea which thread handles this signal in this manner. Maybe it's the init who receives this signal? Or some shell thread? I have no idea.
I'd hazard a guess that the signal is being received by one of your AIO callback threads, or by the very thread which generates the signal. (Prove me wrong and I'll delete this answer.)
Unfortunately per the standard, "[t]he signal mask of [a SIGEV_THREAD] thread is implementation-defined." For example, on Linux (glibc 2.12), if I block SIGUSR1 in main, then contrive to run a SIGEV_THREAD handler from an aio_read call, the handler runs with SIGUSR1 unblocked.
This makes SIGEV_THREAD handlers unsuitable for an application that must reliably and portably handle signals.
The signal mask can be set on a per thread basis, but what about signal handles? If I call sigaction() before creating new threads with pthread_create(), will the new threads get the same signal handler? What if I use sigaction() after pthread_create(), will that change the entire process signal handlers or just the ones of the thread?
There is only ONE signal handler per process. So threads are not relevant in any kind here. The signal handler is called in the thread context which receives the signal. Which thread receives the signal is not specified if multiple threads have not blocked the signal.
You have to take care if multiple threads waits in system calls. Also you have to take care with using timer actions and calls to sleep.
You may also find this answer helpful: POSIX threads and signals
I am confused with the execution about signal handler.
Assuming that i run a single thread(main thread) with a signal handler registered for SIGTERM. Then when the signal SIGTERM is received, does the handler executed in the current thread(main thread) or in another separated thread apart from the main thread.
ANSWER:
i have read a blog about signal handler and reentrant functions. here is the address.
On Linux, the signal handler is executed in the current thread (assuming you mean a scheduled task running that thread, since the kernel scheduler only schedules tasks).
Usually, when a signal is sent, the kernel automagically sets up some call frame(s) for the signal handler (the newly added frames end with sigreturn ...)
See also sigaltstack(2) & sigreturn(2)
Notice that pthread_create(3) is not a syscall (see syscalls(2)...) and is not known to the kernel (since pthread_create is calling clone(2)). Read pthreads(7) and signal(7)
BTW, details are probably different on various POSIX systems (Linux, MacOSX, Solaris, ...)
Reading about interrupts in linux, I understand that their handlers will run till completion (lets not consider the bottom halves here). So, assume that my code has SIGINT handler registered (using the signal()/sigaction() call) with a while(1)-loop in it (i.e the handler never returns).
If I quit my program abruptly while running, then shouldn't this scenario freeze my machine entirely? Won't my machine with only one CPU core go into an infinite loop?
What I mean is; since my interrupt handler is not returning, won't the CPU be stuck in executing the while(1) code only? (i.e no other process will get the chance of running, because there won't be any context-switch/preemption inside the handler or can the interrupt handler get preempted in between running the while(1) loop?)
You definitely mix signal handlers and interrupt handlers, despite they have similar handling. Unlike you are writing kernel code you won't meet interrupt handlers directly.
But, game rules for signal handlers are very similar. You should either exit from a signal handler or finish the program (and, the latter is analog for stopping the whole system, for the kernel land). This includes exotic ways for exiting signal handlers as longjmp().
From kernel POV, a process in forever loop in an interrupt handler doesn't differ from a process with the same loop in a usual code piece like main(). Entering a signal handler modifies signal mask but doesn't change things radically. Such process can be stopped, traced, killed in the same manner as outside of signal.
(All this doesn't concern some special process classes with advanced credentials. E.g. X Window server can be special because it disables some kernel activity during its video adapter handling. But you likely should know the needed safety rules when writing such software.)
I wrote a simple multithreaded application in C++11 on Linux platform and I would like to terminate the server and its running threads by sending SIGINT signal.
Obviously my server application uses thread support from C++11 (std::thread etc.). Although I found some support for signal handling in C++11 (std::signal), I couldn't find any support for handling signals in multithreaded environment.
So my question is - is there any way how to handle signals in multithreaded application in C++11 or do I have to rely back on pthreads just because my application needs to deal with signals?
2.4 Signal Concepts:
At the time of generation, a determination shall be made whether the signal has been generated for the process or for a specific thread within the process. Signals which are generated by some action attributable to a particular thread, such as a hardware fault, shall be generated for the thread that caused the signal to be generated. Signals that are generated in association with a process ID or process group ID or an asynchronous event, such as terminal activity, shall be generated for the process.
...
Signals generated for the process shall be delivered to exactly one of those threads within the process which is in a call to a sigwait() function selecting that signal or has not blocked delivery of the signal.
In the light of the above, in a multi-threaded process a common solution is to block all signals one intends to handle in all threads but one. That one thread would normally handle all process signals and tell other threads what to do (e.g. terminate) and is often the main thread. It easy to block the signals in the main thread before creating other threads, that inherit the signal mask of the parent thread. Once the main thread is done creating child threads and is ready to handle signals it must unblock those.
Unfortunately, C++11 does not provide any means for that. You have to use POSIX functions. Scroll down to Signalling in a Multi-Threaded Process in pthread_sigmask for an example that creates a special signal handling thread. The latter is not necessary if you are using an event loop in the main thread that can handle signals, just unblock the signals before entering the event loop.