Yaron Cohen-Tal
Yaron Cohen-Tal

Reputation: 2185

In Linux/C++, does a signal sent to a thread/process make it become active?

In Linux, when a signal is sent to a process/thread (for whatever reason), is the signal handler (assuming there is one, and the signal isn't blocked) called immediately?

I mean, I'm pretty sure that in the process/thread that handles the signal it will be called immediately, but I mean with respect to other processes/threads.

And if the handler is called immediately, will it also make the corresponding process/thread active (so that its normal execution continues immediatly)?

EDIT

As my original question seems to have been misunderstood, I'll try to explain again with an example.

Lets say in my computer I have a single CPU, and 2 processes running, process 'A' and process 'B'. And assume none of them is blocking in a system call (like sleep). Normally, I guess, the OS will switch between executing process 'A' and process 'B', after small periods of time (e.g. execute process 'A' for 100ms, then process 'B' for 100ms, then process A again for 100ms, etc.). Let's say process 'A' is now the active process (i.e. it's the one now occupying the CPU). Say now that process 'A' sends a signal to process 'B' (or, alternately, the OS sends this signal to process 'B', for whatever reason). Process 'B' has registered an handler for that signal, and is not blocking it. So the question is, will the OS now immediately stop executing process 'A' and switch to executing the signal handler of process 'B'? And if the answer is yes, will it afterwards immediately continue executing process 'B' (The normal code, not the signal handler), or switch back to executing process 'A', and only after some small period of time resume with executing process 'B'?

And then the same questions can be asked about threads rather than processes.

Upvotes: 5

Views: 2683

Answers (4)

incompetent
incompetent

Reputation: 1822

No, signals are delivered on context switch only. Upto that time all signals will be queued. Among many signals of same type, usually Only one signal is delivered to the destination. So i am comfortable to sat that more signals destroyed than delivered. I suggest you to consult chapter regarding any unix book book. My favorite is understanding linux kernel and linux kernel development. if you still need techincal help please comment about it

Upvotes: 3

Klaus
Klaus

Reputation: 25603

And if the handler is called immediately, will it also make the corresponding process/thread active (so that its normal execution continues immediatly)

Your signal handler has its own context. So there is no thread which must be activated for handling your signal. But there are some issues which must be kept in mind. If your thread is waiting with some syscalls like sleep or read/write or any other blocking operation, this system call will be interrupted and the return value from that call give you the information, that your process ( not thread! ) has received a signal.This return value is EINTR. If your thread is simply running or sleeping without waiting on a system call, nothing else is happened! Simply the handler is invoked without any changes in scheduling your threads inside your process.

Upvotes: 0

WedaPashi
WedaPashi

Reputation: 3872

Yes, the handler will be called immediately. Suppose I have a process coded as below.

#include <stdio.h>
#include <signal.h>

void handle_signal(int signal);

volatile int i = 1;

int main( )
{
    struct sigaction sa;

    // Setup the sighub handler
    sa.sa_handler = &handle_signal;

    // Block every signal during the handler
    sigfillset(&sa.sa_mask);

    while(1)
    {
        if(i == 1)
        {
            printf("A");
        }
    }
    return 0;
}

void handle_signal(int signal) {
    /*
     * Please note that printf et al. are NOT safe to use in signal handlers.
     * Look for async safe functions.
     */
    const char *signal_name;
    sigset_t pending;

    // Find out which signal we're handling
    switch (signal) {
        case SIGHUP:
            signal_name = "SIGHUP";
            break;
        case SIGSTOP:
            i = 0;
            signal_name = "SIGSTOP";
            break;
        case SIGCONT:
            signal_name = "SIGCONT";
            i = 1;
            break;
        default:
            fprintf(stderr, "Caught wrong signal: %d\n", signal);
            return;
    }
}

This prints A on shell all the time unless it receives SIGSTOP signal. So, open the shell and do kill -STOP <pid of above process>
Verify that process is stopped, and then from the shell send the SIGCONT signal using kill -CONT <pid of above process>

Upvotes: 0

Danke Xie
Danke Xie

Reputation: 1797

There are two cases: when the signaled process is active, and when it is blocked.

For the former case, according to http://www.tldp.org/LDP/tlk/ipc/ipc.html, the process would handle the signal when it exits from a system call. This would mean that a normal instruction like a = b+c (or its equivalent machine code) would not be interrupted because of signal. Signal handling may also be delayed in a CPU-intensive process.

However, when the process is blocked, it depends on whether the kernel function being called is interruptible (e.g., wait_event_interruptible). If it is interruptible, the process will wake up, otherwise, it will not until it leaves the uninterruptible function (due to IRQ, for instance).

Upvotes: 2

Related Questions