1
$\begingroup$

A process can receive two kinds of signals classified based on the source and reason.

  • Synchronous are the one that are generated by illegal memory access or division by zero.
  • Asynchronous are the one that are generated by another process like SIGKILL and etc.

Quoting from the 9e OSC Book by Prof. Galvin, topic Signal Handling (Section 4.6.2)

A signal may be received either synchronously or asynchronously, depending on the source of and the reason of the event being signaled

...

Examples of synchronous signal incude illegal memory access or and division by zero $0$. ... delivered to the same process that performed the operation that caused the signal.

When signal is generated by an event external to the running process, that process receives the signal asynchronously. Examples of such signal include terminating a process with specific keystrokes (such as CTRL-C) and timer expire (SIGALRM from sleep)

In the both cases, the signal must be handled either by custom or default handler. For the synchronous it is crashing the running process, and in asynchronous, it is using the default routine whatsoever is defined in the system.

Here is the list of questions I have in my mind right now:

  1. What does exactly Synchronous and Asynchronous means here?
  2. In the synchronous, who is waiting for the receiver process to respond?
  3. If both of them are need to be handled, then in my opinion, only priority of the execution would be the difference between these two. Does that mean synchronous signals have more priority?
  4. Can we call synchronous signals as exceptions (or interrupts)? For example we have ZeroDivisionError or FileNotFoundError and all.
$\endgroup$
2
  • 1
    $\begingroup$ Please mark exactly which parts of this post were copied from the book, using Markdown quotation blocks and/or quotation marks. It is not enough to append a reference to the end of the question, you must also clearly mark which parts are copied. See cs.stackexchange.com/help/referencing. Also, please provide a proper reference to the book, which should include at least the full title of the book, the full name of the author, and which section/chapter you are quoting from. $\endgroup$
    – D.W.
    Commented Feb 1 at 22:13
  • $\begingroup$ Yes, your point makes sense to me. I have edited the post. Thanks for the comment. Let me know if anything is missing :) $\endgroup$
    – tbhaxor
    Commented Feb 2 at 10:03

1 Answer 1

0
$\begingroup$

Answering the questions in the same order:

  1. If the source of the signal is within current process, then it is synchronous because it is handled immediately and the OS sends interrupt to the process. Asynchronous is when external tool sends signal to process, for example using kill tool or Ctrl+C and so on. ref

  2. "Waiting for receiver" does not make sense, both the cases the receiver would be target process. The difference lies in the source.

  3. There is no priority kind of thing here in the scene. But a good point to note, SIGKILL and SIGSTOP can't be handled within program, their default handle will be executed and attaching handler to it would return error (check code and bonus section).

  4. Yes we can call it. But, that is related to particular programming. Signals are more general and OS specific keyword in this context.

The following code is generated from the ChatGPT, and it works fine. I have tested it.

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>

void signal_handler(int sig, siginfo_t *info, void *context) {
    (void)context; // Unused parameter

    switch (sig) {
        case SIGFPE:
            printf("Caught SIGFPE: Arithmetic error, such as divide by zero.\n");
            break;
        case SIGSEGV:
            printf("Caught SIGSEGV: Invalid memory reference.\n");
            if (info) {
                printf("Sent by process: %d\n", info->si_pid);
            }
            break;
        case SIGINT:
            printf("Caught SIGINT: Interrupt from keyboard (Ctrl+C).\n");
            if (info) {
                printf("Sent by process: %d\n", info->si_pid);
            }
            break;
        default:
            printf("Caught unhandled signal: %d\n", sig);
            break;
    }
}

int main() {
    struct sigaction act;
    memset(&act, 0, sizeof(act));

    // Set the handler to use the sa_sigaction field
    act.sa_sigaction = signal_handler;

    // Set the SA_SIGINFO flag to use the sa_sigaction field, not sa_handler
    act.sa_flags = SA_SIGINFO;

    // Register the signal handler for SIGFPE, SIGSEGV, and SIGINT
    sigaction(SIGFPE, &act, NULL);
    sigaction(SIGSEGV, &act, NULL);
    sigaction(SIGINT, &act, NULL);

    // A demonstration attempt to handle SIGKILL, which will not work
    if (sigaction(SIGKILL, &act, NULL) < 0) {
        perror("Cannot catch SIGKILL");
    }

    printf("PID: %d\n", getpid());
    printf("Try causing a divide by zero, segmentation fault, or press Ctrl+C\n");

    // Infinite loop to keep the program running until a signal is caught
    while (1) {
        sleep(1);
    }

    return 0;
}

Bonus: As per the man pages, SIGKILL and SIGSTOP can't be blocked ref. This is because SIGKILL is meant to immediately terminate the process without giving it time to release the resources (in this case memory, cpu and etc will be reclaimed by the OS). SIGSTOP instructs the operating system to stop a process for later resumption. These two can be blocked by kernel, but not user-space processes.

In this example you will see CTRL+C will not close the process, only kill -9 PID will terminate the process. Now imagine what if you were allowed to block it, you won't be able to terminate the process at all.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.