c - Why doesn't SigPnd change in proc<pid>status? - Stack Overflow

admin2025-04-19  0

I am trying to understand the signals in POSIX/Linux. I wrote this test.c program:

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

void handler(int signum) {
    printf("\nGoodbye!\n"); exit(0);
}

int main() {
    struct sigaction sa = { .sa_handler = handler };

    // Intercept SIGINT
    sigemptyset(&sa.sa_mask);
    if (sigaction(SIGINT, &sa, NULL) == -1) {
        perror("sigaction"); exit(EXIT_FAILURE);
    }

    signal(SIGUSR1, SIG_IGN); // Ignore SIGUSR1

    // Block SIGUSR2
    sigset_t mask;
    sigemptyset(&mask);
    sigaddset(&mask, SIGUSR2);
    sigprocmask(SIG_BLOCK, &mask, NULL);

    // Simulate work for 10 seconds
    for (int i = 0; i < 10; i++) {
        printf("Working... %d\n", i);
        sleep(1);
    } 
    sigprocmask(SIG_UNBLOCK, &mask, NULL);
}

During the execution, I send:

kill -s USR2 $(pgrep test)

Then quickly after that:

cat /proc/`pgrep test`/status | grep Sig
SigQ:   1/256970
SigPnd: 0000000000000000
SigBlk: 0000000000000800
SigIgn: 0000000000000200
SigCgt: 0000000000000002

SigCgt shows me that SIGINT is intercepted, SigIgn shows that SIGUSR1 is ignored and SigBlk shows that SIGUSR2 is blocked.

In my understanding, sending a signal to a process that is blocked by the process will be pending until the unblock. However I don't see any effect on SigPnd

Any explanation?

I am trying to understand the signals in POSIX/Linux. I wrote this test.c program:

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

void handler(int signum) {
    printf("\nGoodbye!\n"); exit(0);
}

int main() {
    struct sigaction sa = { .sa_handler = handler };

    // Intercept SIGINT
    sigemptyset(&sa.sa_mask);
    if (sigaction(SIGINT, &sa, NULL) == -1) {
        perror("sigaction"); exit(EXIT_FAILURE);
    }

    signal(SIGUSR1, SIG_IGN); // Ignore SIGUSR1

    // Block SIGUSR2
    sigset_t mask;
    sigemptyset(&mask);
    sigaddset(&mask, SIGUSR2);
    sigprocmask(SIG_BLOCK, &mask, NULL);

    // Simulate work for 10 seconds
    for (int i = 0; i < 10; i++) {
        printf("Working... %d\n", i);
        sleep(1);
    } 
    sigprocmask(SIG_UNBLOCK, &mask, NULL);
}

During the execution, I send:

kill -s USR2 $(pgrep test)

Then quickly after that:

cat /proc/`pgrep test`/status | grep Sig
SigQ:   1/256970
SigPnd: 0000000000000000
SigBlk: 0000000000000800
SigIgn: 0000000000000200
SigCgt: 0000000000000002

SigCgt shows me that SIGINT is intercepted, SigIgn shows that SIGUSR1 is ignored and SigBlk shows that SIGUSR2 is blocked.

In my understanding, sending a signal to a process that is blocked by the process will be pending until the unblock. However I don't see any effect on SigPnd

Any explanation?

Share Improve this question edited Mar 5 at 20:18 pilcrow 58.9k14 gold badges100 silver badges144 bronze badges asked Mar 5 at 16:12 nowoxnowox 29.3k49 gold badges174 silver badges355 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

You need to look at ShdPnd (signals pending directed to the whole process), not SigPnd (signals pending directed to that specific thread):

$ kill -s USR2 $(pgrep test)
$ cat /proc/`pgrep test`/status | grep -E 'Sig|Shd'
SigQ:   1/256970
SigPnd: 0000000000000000
ShdPnd: 0000000000000800
SigBlk: 0000000000000800
SigIgn: 0000000000000200
SigCgt: 0000000000000002

The kill command uses the kill syscall, which directs the signal to the whole process. To have a signal appear in SigPnd in /proc/PID/status you would have to direct it specifically to the main thread using the tgkill syscall (not sure if there is a command that can do this for you).

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1745021606a280414.html

最新回复(0)