Linux信号高级应用

Sigaction

SYNOPSIS
       #include <signal.h>
       int sigaction(int signum, const struct sigaction *act,
                     struct sigaction *oldact);

功能:

sigaction函数用于改变进程接收到特定信号后的行为。

参数

第一个参数为信号的值,可以为除SIGKILL及SIGSTOP外的任何一个特定有效的信号(为这两个信号定义自己的处理函数,将导致信号安装错误)

第二个参数是指向结构sigaction的指针,在结构 sigaction的实例中,指定了对特定信号的处理,可以为空,进程会以缺省方式对信号处理

第三个参数oldact指向的对象用来保存原来对相应信号的处理,可指定oldact为NULL。

返回值

函数成功返回0,失败返回-1

sigaction结构体

第二个参数最为重要,其中包含了对指定信号的处理、信号所传递的信息、信号处理函数执行过程中应屏蔽掉哪些函数等等

/*
struct sigaction {
  //信号处理程序 不接受额外数据(比较过时)
	void (*sa_handler)(int);

  //信号处理程序能接受额外数据,和sigqueue配合使用(支持信号排队,信号传送其他信息),推荐使用
	void (*sa_sigaction)(int, siginfo_t *, void *);
  
  sigset_t sa_mask; 	//屏蔽
	int sa_flags; 		//表示信号的行为:SA_SIGINFO表示能接受数据
	void (*sa_restorer)(void); //废弃不用了
};
*/

//示例
#define ERR_EXIT(m)             {              perror(m);              exit(EXIT_FAILURE);            }

void onSignalAction(int signalNumber)
{
    switch(signalNumber)
    {
    case SIGINT:
        cout << "SIGINT = " << signalNumber << endl;
        break;
    case SIGQUIT:
        cout << "SIGQUIT = " << signalNumber << endl;
        break;
    default:
        cout << "Other Signal ..." << endl;
        break;
    }
}

void onSa_SignalAction(int signalNum, siginfo_t *signalInfo, void *p)
{
    cout << "signalNum = " << signalNum << endl;
}

int main()
{
  struct sigaction act;
  //注意:回调函数句柄sa_handler、sa_sigaction只能选其一!!!
    //act.sa_handler = onSignalAction;
    act.sa_sigaction = onSa_SignalAction;
    if (sigaction(SIGINT,&act,NULL) == -1)
        ERR_EXIT("sigaction error");

    while (true)
    {
        pause();
    }

    return 0;
}

siginfo_t结构:

       The siginfo_t parameter to sa_sigaction is a struct with the following elements

/*
siginfo_t{
    int      si_signo;    /* Signal number */
    int      si_errno;    /* An errno value */
    int      si_code;     /* Signal code */
    int      si_trapno;   /* Trap number that caused
                                        hardware-generated signal
                                        (unused on most architectures) */
    pid_t    si_pid;      /* Sending process ID */
    uid_t    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_value;    /* Signal value */
    int      si_int;      /* POSIX.1b signal */
    void    *si_ptr;      /* POSIX.1b signal */
    int      si_overrun;  /* Timer overrun count; POSIX.1b timers */
    int      si_timerid;  /* Timer ID; POSIX.1b timers */
    void    *si_addr;     /* Memory location which caused fault */
    long     si_band;     /* Band event (was int in
                                        glibc 2.3.2 and earlier) */
    int      si_fd;       /* File descriptor */
    short    si_addr_lsb; /* Least significant bit of address
                                        (since Linux 2.6.32) */
}
*/

//示例:自己写signal函数
__sighandler_t mySignal(int sig, __sighandler_t handler)
{
    struct sigaction act;
    struct sigaction oldact;
    act.sa_handler = handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;

    if (sigaction(sig, &act, &oldact) < 0)
        return SIG_ERR;

    return oldact.sa_handler;
}

//示例:测试sigaction结构体第三个参数sigset_t sa_mask的作用
void handler(int sig)
{
    //信号处理函数执行的时候,阻塞sa_mask中的信号,但是SIGQUIT信号最终还会抵达
    printf("recv a sig=%d\n", sig);
    sleep(5);
}

int main(int argc, char *argv[])
{
    struct sigaction act;

    //设置响应函数
    act.sa_handler = handler;
    //设置屏蔽字成员
    sigemptyset(&act.sa_mask);
    sigaddset(&act.sa_mask, SIGQUIT);
    act.sa_flags = 0;

    //注册响应信号SIGINT函数
    sigaction(SIGINT, &act, NULL);
    pause();

    return 0;
}

sigqueue

SYNOPSIS
       #include <signal.h>
       int sigqueue(pid_t pid, int sig, const union sigval value);

功能

sigqueue是新的发送信号系统调用,主要是针对实时信号提出的支持信号带有参数,与函数sigaction()配合使用。

和kill函数相比多了一个参数:const union sigval value,因此sigqueue()可以比kill()传递更多的信息,但sigqueue()只能向一个进程发送信号,而不能发送信号给一个进程组。

参数

参数1是指定接收信号的进程id,参数2确定即将发送的信号;

参数3是一个联合数据结构union sigval,指定了信号传递的参数,即通常所说的4字节值。

返回值

成功返回0,失败返回-1

sigval联合体

typedef union sigval{
    int sival_int;
    void *sival_ptr;
} sigval_t;

//综合实验sigaction+sigqueue
inline void err_exit(const char *str)
{
    perror(str);
    exit(EXIT_FAILURE);
}

void onSa_SignalAction(int signalNum, siginfo_t *signalInfo, void *p)
{
    cout << "signalNum = " << signalNum << endl;
    //int recValue = signalInfo -> si_value.sival_int;  同下
    int recValue = signalInfo -> si_int;
    cout << "recvValue = " << recValue << endl;
}

int main()
{
    struct sigaction act;

    sigemptyset(&act.sa_mask);
    act.sa_flags = SA_SIGINFO;
    act.sa_sigaction = onSa_SignalAction;
    if (sigaction(SIGINT,&act,NULL) == -1)
        err_exit("sigaction error");

    pid_t pid = fork();
    if (pid == -1)
        err_exit("fork error");
    else if (pid == 0)  //In Child
    {
        /*
        typedef union sigval{
            int sival_int;
            void *sival_ptr;
        } sigval_t;
        */

        //union sigval signalValue; 同下
        sigval_t signalValue;
        signalValue.sival_int = 256;
        sleep(2);

        //给父进程发送SIGINT信号
        sigqueue(getppid(),SIGINT,signalValue);
    }

    pause();

    return 0;
}
时间: 2024-08-24 19:02:21

Linux信号高级应用的相关文章

Linux/UNIX高级I/O

高级I/O 非阻塞IO 非阻塞I/O使我们可以调用open.read和write这样的I/O操作,并使这些操作不会永久阻塞.如果这种操作不能完成,则调用立即出错返回,表示该操作如继续执行将阻塞. 对于一个给定的描述符有两种方法对其指定非阻塞I/O: 1)      如果调用open获得描述符,则可指定O_NONBLOCK标志 2)      对于已打开的一个描述符,则可调用fcntl,由该函数打开O_NONBLOCK文件状态标志. 记录锁 记录锁的功能是:当一个进程正在读或修改文件的某个部分时,

Linux 信号signal处理机制(ZZ)

http://www.cnblogs.com/taobataoma/archive/2007/08/30/875743.html 信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念.Linux对信号机制的大致实现方法.如何使用信号,以及有关信号的几个系统调用. 信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断.从它的命名可以看出,它的实质和使用很象中断.所以,信号可以说是进程控制的一部分. 一.信号的基本概念 本节先介绍信号的一些基本概念,然后

LINUX 信号概念详解

LINUX 信号概念详解 我们运行如下命令,可看到Linux支持的信号列表: # kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP

Linux信号列表

我们运行如下命令,可看到Linux支持的信号列表:~$ kill -l1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR213) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) S

Linux信号(signal) 机制分析

[摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核对于信号的处理流程包括信号的触发/注册/执行及注销等.最后介绍了应用层的相关处理,主要包括信号处理函数的安装.信号的发送.屏蔽阻塞等,最后给了几个简单的应用实例. [关键字]软中断信号,signal,sigaction,kill,sigqueue,settimer,sigmask,sigprocmask,sigset_t 1       信

Linux信号详解

Linux信号详解 一 信号的种类 可靠信号与不可靠信号, 实时信号与非实时信号 可靠信号就是实时信号, 那些从UNIX系统继承过来的信号都是非可靠信号, 表现在信号 不支持排队,信号可能会丢失, 比如发送多次相同的信号, 进程只能收到一次. 信号值小于 SIGRTMIN的都是非可靠信号. 非可靠信号就是非实时信号, 后来, Linux改进了信号机制, 增加了32种新的信号, 这些信 号都是可靠信号, 表现在信号支持排队, 不会丢失, 发多少次, 就可以收到多少次. 信号值 位于 [SIGRTM

Linux 信号signal处理机制

信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念.Linux对信号机制的大致实现方法.如何使用信号,以及有关信号的几个系统调用. 信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断.从它的命名可以看出,它的实质和使用很象中断.所以,信号可以说是进程控制的一部分. 一.信号的基本概念 本节先介绍信号的一些基本概念,然后给出一些基本的信号类型和信号对应的事件.基本概念对于理解和使用信号,对于理解信号机制都特别重要.下面就来看看什么是信号. 1.基本

Linux 信号理解(二)

linux下信号基本概念见:Linux 信号理解(一) 接下来讲重点讲述信号捕捉设定 #include<stdio.h> #include<signal.h> #include<errno.h> void capture_sig(int num) { int n=4; printf("capture_sig is called \n"); while(n--) { sleep(1); printf(" num:%d \n",num

Linux信号实践(2) --信号分类

信号分类 不可靠信号 Linux信号机制基本上是从UNIX系统中继承过来的.早期UNIX系统中的信号机制比较简单和原始,后来在实践中暴露出一些问题,它的主要问题是: 1.进程每次处理信号后,就将对信号的响应设置为默认动作.在某些情况下,将导致对信号的错误处理:因此,用户如果不希望这样的操作,那么就要在信号处理函数结尾再一次调用signal(),重新安装该信号. 2.因此导致, 早期UNIX下的不可靠信号主要指的是进程可能对信号做出错误的反应以及信号可能丢失. Linux支持不可靠信号,但是对不可