跟着iMX28x开发套件学linux-06

本文深入探讨了Linux系统中信号的概念及应用,详细介绍了信号的基本原理、处理方式以及sigaction函数的使用方法。通过实例演示了如何自定义信号处理函数,包括如何设置信号处理方式和屏蔽信号,展示了信号在进程间通信中的重要作用。

六、linux应用编程之四:信号

linux同时运行着多个进程,进程通信就显得很有必要。实际上平时使用linux系统的时候也经常利用信号对进程进行通信,比如想要shell里终止一个正在运行的程序的时候,按下Ctrl+c的时候,等于向进程发送了一个SIGINT信号。

信号本身并不复杂,就是int类型的常量,用kill -l命令可以查看支持的信号。需要关注的是进程对信号的处理。当进程接收到信号,一般有三种响应方式:一是类似中断服务函数的响应方式;二是进程忽略信号,即不进行响应;三是系统默认的响应方式,一般是终止线程。

对于一般的信号,线程采用系统默认的响应方式即可,但是某些特别的情况下,系统默认的响应方式不能满足需求,那就需要自己编写响应函数,然后把该信号的响应方式设置为中断服务的响应方式,当然这里的中断服务函数要指向事先编写好的响应函数。

设置响应方式的函数为sigaction()函数,下面介绍这个函数。

sigaction()函数

1) 函数原型 int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);

2) 输入参数 signum,哪个信号的响应要被设置;

*actsigaction结构体的指针,用来配置设置项;

*oldactsigaction结构体的指针,可以为NULL

3)  int,成功返回0,失败返回-1

这个函数从表面看只是选定了要设置响应的信号,但是关于具体的设置并没有表现出来,比如要把中断服务函数设置成哪个响应函数,在处理选定的信号的时候要不要屏蔽一些信号等等。实际上这些内容都在sigaction结构体中。

sigaction结构体

   

1) *sa_handler : 函数指针,指向有一个int类型参数以及无返回值的函数。

2) *sa_sigaction : 同上,输入参数不同,指向更高级的响应函数,可以为空。

3) sa_mask : 屏蔽设置,设置哪些信号被屏蔽。

4) sa_flags : 响应选项,可以配置响应方式等的参数。

在实际使用的时候,先声明一个sigaction结构体,然后逐个初始化这个结构体的值。sa_handler就是指定信号发生时调用的函数的指针;sa_sigaction指向更高级的响应函数,前提是sa_flags要设置SA_SIGINFOsa_mask可以调用 sigemptyset()sigaddset()sigdelset()分别对这个信号集进行清空、增加和删除被屏蔽信号的操作,将sa_mask的引用作为这三个函数的输入参数即可;sa_flags可以是多个配置选项的或,取值如下:

flags

描述

SA_RESTART

使被信号打断的系统调用自动重新发起。

SA_NOCLDSTOP

使父进程在它的子进程暂停或继续运行时不会收到SIGCHLD 信号。

SA_NOCLDWAIT

使父进程在它的子进程退出时不会收到 SIGCHLD 信号,这时子进程如果退出也不会成为僵尸进程。

SA_NODEFER

使对信号的屏蔽无效,即在信号处理函数的执行期间仍能发出这个信号。

SA_RESETHAND

信号被处理后重新设置处理方式到默认值。

SA_SIGINFO

使用 sa_sigaction 成员而不是 sa_handler 作为信号处理函数。

 使用Ctrl+c向程序发送SIGINT信号示例

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

//sa_handler function
void ouch(int sig){
    printf("\nOuch! I got a signal %d\n", sig);
}

int main(){
    
    struct sigaction act;
    act.sa_handler = ouch;                //link handler
    sigemptyset(&act.sa_mask);            //empty signal mask
    act.sa_flags = SA_RESETHAND;            //use default after due signal
    sigaction(SIGINT, &act, NULL);        //use params to set signal action
    
    while(1){
        printf("sleep(1)\n");
        sleep(1);
    }
    return 0;
}

 

运行结果:

   

父进程使用kill()向子进程发送信号示例

   

  运行结果:

   

 

转载于:https://www.cnblogs.com/liangda/p/9911966.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值