Linux信号及信号处理学习总结

本文详述了Linux下的信号处理,包括注册信号处理函数(signal和sigaction)、信号集的操作(sigemptyset等)以及信号阻塞(sigprocmask、sigsuspend等)。此外,还介绍了信号发送函数(kill、raise、alarm、setitimer)及其用法,为理解和使用Linux信号提供了全面的总结。

信号处理

注册信号调用函数

函数(1)void (*signal (int signumber,void((*func)int)))(int)

头文件:signal.h

说明:func为指向调用函数的函数指针,其也可以取特定值:SIG_IGNSIG_DFL,其中SIG_IGN表示忽略signumber所指信号,SIG_DFL表示调用系统定义的默认处理。signal函数返回值类型同参数func,其为一个指向某个返回值为空的带有一个整数参数的函数指针。该调用成功时返回上次该信号的处理函数,错误时返回SIG_ERR

函数(2)int sigaction(int sigunumber,const struct sigaction *act ,struct sigaction *oldact)

头文件:signal.h

说明: 该函数不仅可以实现signal函数的功能,还可以提供更加详细的信息,确切了解进行接收到信号时所发生的细节。其中sigaction结构如下:

struct sigaction{

    void (*sa_handler)(int);

    void (*sa_sigaction)(int,siginfo_t *,void *);

    sigset_t sa_mask;

    int sa_flags;

}

sa_hander为指向信号处理函数的地址,sa_sigaction为指向函数的指针。其中siginfo_t结构体如下:

typedef struct siginfo{

    int si_signo;//signal number

    int si_errno;//an errno value

    int si_code;//signal code

    int si_pid;//sending process ID

    INT si_uid;//real user ID of sending process

    int si_status;//exit value or signal

    clock_t si_utime;//user time consumed

    clock_t si_stime;//system time consumed

    sigval_t si_balue // signal value

    int si_int ;//POSIX.1b signal

    void *si_ptr;//POSIX.1b signal

    void *si_addr;//memory location that caused fault

    int si_band;//band event

    int si_fd;//file descriptor;

} siginfo_t;

sa_flag指示信号处理函数的不同选项,通过位运算来实现所需要的选项设置。如果赋值为0则选用所有的默认选项,其选项参数如下:

SA_NOCLDSTOP:用于指定信号SIGCHLD,当子进程被中断时,不产生此信号,当且仅当子进程结束时产生此信号;

SA_NOCLDWAIT:当信号为SIGCHLD时,此选项可以避免子进程僵死;

SA_NODEFER:当信号处理程序正在运行时,不阻塞对于信号处理函数自身的信号功能;

SA_NOMASK:SA_NODEFER

SA_ONESHOT:当用户注册的信号处理函数被调用过一次之后,该信号的处理程序恢复为默认的处理函数;

SA_RESETHAND:SA_ONESHOT

SA_RESTART:使本来不能进行自动重新运行的系统调用自动重新运行;

SA_SIGINFO:表明信号处理函数是有SA_SIGACTION指定,而不是有SA_HANDLER指定,它将显示更多处理函数的信息。

sa_mask指定在信号处理程序执行过程中,哪些信号应当被阻塞。缺省情况下当前信号本身被阻塞,防止信号的嵌套发送,除非指定SA_NODEFER或者SA_NOMASK标志位。此外,sa_mask指定的信号阻塞的前提条件是在由sigaction安装信号的处理函数执行过程中由sa_mask指定的信号才被阻塞。

信号集

函数(1):(1) int sigemptyset(sigset_t *set);

           (2) int sigfillset(sigset_t *set);

           (3) int sigaddset(sigset_t *set,int signumber);

           (4) int sigdelset(sigset_t *set ,int signumber);

头文件:signal.h

说明:set为指向信号集的指针,参数signumber表示一个信号,可以用信号名表示。

    sigemptyset用于将set所指向的信号集设定为空,即不包含任何信号;

    sigfillset用于将那个set所指向的信号集设定为满,即包含所有信号;

   sigaddset用于将signumber所代表的信号加到set所指向的信号集中;

    sigdelset用于将signumber所代表的信号从set所指向的信号集中删除。

函数(2):int sigismember(const sigset_t set,int signumber);

头文件:signal.h

说明:用于检测一个信号signumber是否在set所指向的信号集中,若signumber属于该信号集则返回1,否则返回0

信号阻塞

通过信号阻塞可以实现当进程收到信号后,不希望立即中断进程的执行,又不想忽略该信号,而是希望延迟一段时间来执行。

函数(1)(1)int sigprocmask(int how,const sigset_t *set,sigset_t *oldest);

       (2)int sigsuspend(const sigset_t *sigmask);

       (3)int sigpending(sigset_t *set);

头文件:signal.h

说明:

sigprocmask用于检测和改变进程的信号掩码,信号掩码是由被阻塞的发送给当前进程的信号组成的信号集。set指向一个信号集时,how用于表示sigprocmask将如何对set所指向的信号集进行操作,当setNULL时,how的取值没有意义。当oldset不为NULL时,函数sigprocmask将进程的信号掩码返回给oldset

sigsuspend用于将进程挂起,函数被调用时,sigmask中的信号被赋值给信号掩码。之后信号被挂起,至到进程捕捉到信号调用处理函数并执行完毕返回时,sigsuspend返回。信号掩码恢复为函数调用前的值,当时将errno设置为EINR。进程结束信号可以使其立即终止。其中how的取值如下:

SIG_BLOCK:set所指向的信号集中所包含的信号加到当前的信号掩码中。即:信号掩码与set信号集做逻辑加操作;

SIG_UNBLOCK:set所指向的信号集中所包含的信号从当前的信号掩码中移除。即:信号掩码与set信号集做逻辑减操作;

SIG_SETMAST设定新的当前信号掩码为set所指向的信号集中所包含的信号。即:set信号集对信号掩码进行赋值操作。

sigpending用于将被搁置的信号集合由参数set指针返回。执行成功则返回0,如果有错误则返回-1

函数(2)int pause(void);

头文件:unistd.h

说明:使进程暂停运行,直到一个信号被捕捉并调用处理函数执行返回时,该函数返回。

信号发送

信号发送的关键是要确定给那个进程发送信号以及发送什么信号,此外,能否向某一进程发送特定的信号和用户的权限密切相关。

函数:int kill(pid_t ,int signumber);

           int raise(int signumber);

           unsigned int alarm(unsigned int seconds);

           int setitimer(int which,const struct itimerval *value,struct itimetval);

头文件:sys/types.h  signal.h  unistd.h  sys/time.h 

说明:

         kill函数用于向某一指定的进程或进程组发送信号,pid表示kill函数发送信号对象的进程号或进程组号,当信号成功发送时,返回0,失败是返回-1;其中pid的取值对应关系如下:

取值

含义

pid>0

向进程号为pid的进程发送信号

pid=0

向与发送进程的进程组号的进程发送信号

pid<0

向进程组号为pid绝对值的进程组发送信号

pid=-1

未定义

         raise函数用于向一个进程自身发送信号,参数signumber为所发送的信号编号,调用成功返回0,失败返回-1

         alarm函数用于设定时间片,使系统在一定时间之后发送信号,参数seconds为到下一次产生信号前的间隔时间。信号正常发送时返回0,若心的报警设置在前一次设定尚未结束时发生,则返回前一次设置所剩时间。

         sititimer函数同alarm一样,用于系统在某一时刻发送信号,但它可以更精确的控制程序,参数which表示记时方式,参数value为指向itimerval结构的指针,具体如下:

 

struct itimerval{

         struct timeval it_interval;//每一次触发报警应该被复位的值

         struct timeval it_value;//下一次报警时间

}

struct timeval{

         long tv_sec;

         long tv_isec;

}

which的取值如下:

which

计时方式

发送信号

ITIMET_TEAL

根据系统时间

SIGALRM

ITIMER_PROF

从用户进程开始后计时

SIGPROF

ITIMER_VIRTUAL

只有在用户模式下执行时才可跟踪时间

SIGVTALRM

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值