Signal handling and sigemptyset()

2020-05-17 08:52发布

问题:

Could anyone please explain in a really easy way to understand what sigemptyset() does? Why is it useful? I've read a bunch of definitions but i just don't understand. From what i gather it tracks the signals that are being used for blocking purposes? I'm not really sure i understand why that would be useful. Is it so we do not get that specific signal recursively?

Basic example where sigemptyset() is used:

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

int main(){

struct sigaction act;
sigemptyset(&act.sa_mask);
act.sa_handler=function_name;
act.sa_flags=0;

sigaction(SIGINT, &act, 0);

}

回答1:

sigemptyset simply initializes the signalmask to empty, such that it is guaranteed that no signal would be masked. (that is, all signals will be received) Basically it is similar to a memset(0) but you don't have to know the details of the implementation. So if the sa_mask member is changed you don't need to adjust your code because it will be taken care of by sigemptyset.



回答2:

Take a step back. sigset_t is a construct that represents multiple signals upon which some action is going to be take via some system call (e.g. sigaction) but since the data structure representing sigset_t is opaque there needs to be a reliable way to initialize it. Local variables in C aren't automatically initialized and you can't just assume sigset_t is an integer type and initialize it to zero because it might be a structure or some other unknown type. Thus sigemptyset and sigfillset are provided to reliably empty (turn all signals off) or fill (turn all signal on) the sigset_t representation.

Your actual confusion may be what the signal sets inherent in sigset_t are used for and the answer to that is they are used for multiple things. You may want to block multiple signals in one call by passing a set to appropriate call. Or you may want to check all pending signals in one call. In short, it depends, but a set allows you to operate on multiple signals in one shot rather than a sequential series of actions - something which is particularly problematic with signals because they are asynchronous and subject to all kinds of race conditions.



回答3:

The name says it all. sigemptyset() empties (a variable describing) a set of signals.

That is

sigset_t ss;
sigemptyset(&ss);

initialises a variable of type sigset_t (ss here) to "contain" no signals.

From man sigemptyset (Linux):

sigemptyset() initializes the signal set given by set to empty, with all signals excluded from the set.

[...]

Objects of type sigset_t must be initialized by a call to either sigemptyset() or sigfillset() before being passed to the functions sigaddset(), sigdelset() and sigismember() [...]

From the POSIX specs:

int sigemptyset(sigset_t *set); 

[...]

The sigemptyset() function initializes the signal set pointed to by set, such that all signals defined in POSIX.1-2008 are excluded.