进程间通信方式----信号

信号(SIGNAL)是操作系统的一部分,任何操作系统都离不开信号,信号就是操作系统自带的一套机制,由系统内核维护无需用户管理在操作系统中。信号是以软中断的形式存在的。

信号的官方宏定义及含义

在linux中可以在终端中输入指令man 7 signal来查看

   Signal     Value     Action   Comment
   ──────────────────────────────────────────────────────────────────────
   SIGHUP        1       Term    Hangup detected on controlling terminal
								 or death of controlling process
								 在控制终端收到一个"挂起" 或控制进程死亡时会收到这个信号
   SIGINT        2       Term    Interrupt from keyboard ==> Ctrl+C
   SIGQUIT       3       Core    Quit from keyboard      ==> 来自键盘的退出 Ctrl+\
   SIGILL        4       Core    Illegal Instruction 	 ==> 遇到非法指令
   SIGABRT       6       Core    Abort signal from abort(3) ==> 非正常终止
   SIGFPE        8       Core    Floating point exception	==>遇到一个浮点错误 比如 a/0
   SIGKILL       9       Term    Kill signal				==>杀死信号
   SIGSEGV      11       Core    Invalid memory reference	==>非法内存引用
   SIGPIPE      13       Term    Broken pipe: write to pipe with no ==> 有写无读的管道
								 readers
   SIGALRM      14       Term    Timer signal from alarm(2)	 ==> 超时信号
   SIGTERM      15       Term    Termination signal			 ==> 中止信号
   SIGUSR1   30,10,16    Term    User-defined signal 1		==> 用户自定义信号1
   SIGUSR2   31,12,17    Term    User-defined signal 2		==> 用户自定义信号2
   SIGCHLD   20,17,18    Ign     Child stopped or terminated ==>子进程退出或结束时,父进程收到的信号
   SIGCONT   19,18,25    Cont    Continue if stopped		==> 继续信号,继续停止的进程
   SIGSTOP   17,19,23    Stop    Stop process				==> 停止进程信号 
   SIGTSTP   18,20,24    Stop    Stop typed at terminal		==> 终端发起的停止信号Ctrl+Z
   SIGTTIN   21,21,26    Stop    Terminal input for background process 后台试图从控制端输入
   SIGTTOU   22,22,27    Stop    Terminal output for background process	后台试图从控制端输出

信号的处理方式

  • 忽略:不进行任何处理
  • 默认:采用操作系统的方式去处理信号。例如: ctrl+c就是发送一个信号,将运行的程序终止。(注意:SIGKILL和SIGSTOP只能默认处理)
  • 重定向:采用signal函数捕捉信号,并重新指定信号的处理方式

linux中与信号机制相关的几个接口函数

  • signal:用来捕获一个信号,并修改其信号的处理函数
    头文件:
    #include <signal.h>
    函数原型:
    sighandler_t signal(int signum, sighandler_t handler);
    @signum: 信号值,表示要捕获的信号
    @handler:指定信号处理方式
    1) SIG_IGN 忽略,不进行任何处理
    2) SIG_DFL 默认,采用操作系统默认的信号处理行为
    3) 自定义的信号处理函数的函数名表示由开发者执行决定处理方式
    返回值:失败返回SIG_ERR
#include <stdio.h>
#include <signal.h>

int flag = 1; //标志位,默认初始化为1

/*
自定义的信号处理函数
*/
void function(int signal)
{
    printf("按下ctrl + c\n");
    flag = 0; //标志位设置为0
}

int main()
{
    //捕获信号SIGINT(即ctrl+c)
    if(SIG_ERR == signal(SIGINT, function))
    {
        //函数失败
        perror("signal error");
        return 0;
	}

    //死循环,当运行了function函数使标志位设置为0后结束循环
    while (flag)
        ;

    printf("程序ctrl+c后未结束\n");
    return 0;
}
  • kill:用来给pid指定的进程发送一个sig信号
    头文件:
    #include <sys/types.h>
    #include <signal.h>
    函数原型:
    int kill(pid_t pid, int sig);
    @pid: 进程号,表示发送信号给那个进程
    @sig: 信号,整数(宏),表示要发送的信号
    返回值:成功返回0,失败返回-1,并且errno被设置
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>

int main()
{
    //结束pid为3098的进程(进程pid可以在终端输入ps来查看)
    if(-1 == kill(3098, SIGKILL))
    {
        perror("kill error");
    }

    return 0;
}
  • pause:等待某个信号到来,阻塞进程的执行,直到有信号
    头文件:
    #include <unistd.h>
    函数原型:
    int pouse(void);
    如果该进程执行过程中,没有收到信号,则pause函数会一直等待直到任意信号到来

  • alarm:指定时间后产生一个SIGALRM(超时)信号
    头文件:
    #include <unistd.h>
    函数原型:
    unsigned int alarm(unsigned int seconds);
    @seconds:设置的超时时间(以秒为单位)
    alarm函数不会阻塞进程,调用alarm函数时,程序照常运行下去,只不过,当alarm设定的时间到来后,会产生SIGALRM信号SIGALRM信号的默认处理方式是,输出”闹钟“,同时中止进程。

      	在linux中,如果一个进程中有多个alarm,则以最后设定的时间为准
    
#include <unistd.h>
#include <signal.h>
#include <stdio.h>

/*
自定义的信号处理函数
*/
void function(int signal)
{
    printf("time out!\n");
}

int main()
{
    //捕获信号SIGALRM
    if (SIG_ERR == signal(SIGALRM, function))
    {
        perror("signal error");
    }

    //设置闹钟(由于设置两个闹钟,所以闹钟仅最后一个有效,即5妙后发出SIGALRM(超时)信号)
    alarm(3);
    alarm(10);
    alarm(5);

    //pause函数,阻塞进程,有信号时才结束
    pause();

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值