IO进、线程——进程间通信的信号通信:kill()、raise()、alarm()、pause()、signal()

信号通信

1. 介绍

信号是进程间通信中一种简单而有效的机制,用于通知进程发生了某个事件。当某个进程产生一个信号时,它可以向其他进程发送信号,并触发接收进程的信号处理函数。信号机制可以用于进程之间的异步通信,比如在一个进程执行的过程中,另一个进程可以通过发送信号来中断或修改其执行行为。

信号是内核进程通知用户进程应该干什么了

2. 信号的基本概念

2.1 信号的产生和处理

信号是由操作系统或其他进程发送给目标进程的通知,可以表示某种事件的发生,如按下Ctrl+C键、子进程终止等。进程可以设置信号处理函数来对收到的信号做出响应,处理函数可以是用户自定义的函数。

2.2 信号的类型

信号是用整数表示的,不同的信号有不同的整数值。例如,SIGINT代表终止进程的信号,其整数值为2。Linux系统中有许多不同的信号,每个信号都有特定的含义和用途。

信号名编号信号名编号信号名编号
SIGHUP1SIGRTMIN34SIGRTMAX-955
SIGINT2SIGRTMIN+135SIGRTMAX-856
SIGQUIT3SIGRTMIN+236SIGRTMAX-757
SIGILL4SIGRTMIN+337SIGRTMAX-658
SIGTRAP5SIGRTMIN+438SIGRTMAX-559
SIGABRT6SIGRTMIN+539SIGRTMAX-460
SIGBUS7SIGRTMIN+640SIGRTMAX-361
SIGFPE8SIGRTMIN+741SIGRTMAX-262
SIGKILL9SIGRTMIN+842SIGRTMAX-163
SIGUSR110SIGRTMIN+943SIGRTMAX64
SIGSEGV11SIGRTMIN+1044
SIGUSR212SIGRTMIN+1145
SIGPIPE13SIGRTMIN+1246
SIGALRM14SIGRTMIN+1347
SIGTERM15SIGRTMIN+1448
SIGSTKFLT16SIGRTMIN+1549
SIGCHLD17SIGRTMAX-1450
SIGCONT18SIGRTMAX-1351
SIGSTOP19SIGRTMAX-1252
SIGTSTP20
SIGTTIN21
SIGTTOU22
SIGURG23
SIGXCPU24
SIGXFSZ25
SIGVTALRM26
SIGPROF27
SIGWINCH28
SIGIO29
SIGPWR30
SIGSYS31

2.3 发送信号

发送信号的操作通常由操作系统或其他进程执行。发送信号的常用方法是使用kill命令或系统调用kill()。
①kill():

#include <signal.h>

int kill(pid_t pid, int sig);

功能:往指定进程发送信号
返回值:成功返回0,失败返回-1
参数说明:
pid:向哪个进程发送信号

-1:所有进程(不能用)
0:表示发送信号给指定进程ID的进程。

sig:具体的某个信号(信号类型)

②raise():

int raise(int sig);

功能:向进程自己发送信号
返回值:成功返回0,失败返回非0
sig:要发送的信号
raise(SIGINT); // <==> kill(getpid(), SIGINT);

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

void sig_handler(int signum){
    if(signum == SIGINT){
        printf("收到信号CTRL+C:%d\n",signum);
    }
    if(signum == SIGQUIT){
        printf("收到信号CTRL+\\:%d\n",signum);
    }
}
int main(int argc, char *argv[])
{ 
    int sig1 = SIGINT;
    int sig2 = SIGQUIT;
    //绑定信号
    signal(sig1, sig_handler);
    signal(sig2, sig_handler);
    //自己给自己发信号
    raise(sig1);
    raise(sig2);
    while(1);

    return 0;
} 
~                  

③alarm():

unsigned int alarm(unsigned int seconds);

功能:开启定时器进行计时,时间到了产生SIGALRM信号
返回值:上一次定时过后还剩多少秒,如果是第一次定时返回0
seconds:要定时多久,写0表示取消定时

#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{ 
    int ret = alarm(10);
    printf("开始计时10秒\n");
    printf("上一次还剩下ret 1 = %d 秒\n", ret);

    sleep(3);
    printf("延迟了三秒\n");

    ret = alarm(3);
    printf("上一次还剩下ret 2 = %d 秒\n",ret);

    while(1);

    return 0;
} 

④pause():

int pause(void);

功能:暂定进程,需要收到信号才能继续执行

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

void sig_handler(int signum){
    printf("接收到信号 CTRL+C :%d\n",signum);
}

int main(int argc, char *argv[])
{ 
    int sig = SIGINT;
    signal(sig, sig_handler);
    printf("进程暂停,等待信号……\n");
    pause();
    printf("进程恢复。\n");

    return 0;
} 

3. 信号处理

3.1 设置信号处理函数

进程可以使用系统调用signal()来设置信号处理函数,其原型如下:

#include <signal.h>

void (*signal(int signum, void (*handler)(int)))(int);

或者是下面的

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

功能:绑定信号与某个操作
参数说明:
signum:是要设置处理函数的信号编号
handler:是指向信号处理函数的处理方式。

SIG_IGN:忽略信号
SIG_DFL:默认操作
或者自定义函数,指定信号发生时需要执行的操作。

信号处理函数的定义如下:

void handler(int signum);

信号处理函数接收一个整数参数signum,它是收到的信号的编号。在信号处理函数中,可以对接收到的信号做出相应的处理,如终止进程、忽略信号等。

3.2 默认信号处理行为

对于每个信号,操作系统都有一个默认的信号处理行为。例如,SIGINT信号的默认处理行为是终止进程,而SIGCHLD信号的默认处理行为是忽略。进程可以通过设置信号处理函数来改变默认的处理行为。

信号名含义默认操作
SIGABRT中止进程,如调用abort()函数终止进程
SIGALRM定时器超时终止进程
SIGBUS非法地址访问(总线错误)终止进程
SIGCHLD子进程状态改变忽略
SIGCONT继续运行停止的进程忽略
SIGFPE浮点异常(如除以零)终止进程
SIGHUP终端断开终止进程
SIGILL非法指令终止进程
SIGINT终端中断(如按下Ctrl+C)终止进程
SIGKILL杀死进程终止进程
SIGPIPE管道破裂(写入一个没有读取端)终止进程
SIGQUIT终端退出(如按下Ctrl+\)终止进程
SIGSEGV无效的内存引用终止进程
SIGSTOP停止进程停止进程
SIGTERM终止信号(如kill命令)终止进程
SIGTSTP终端挂起(如按下Ctrl+Z)停止进程
SIGTTIN后台进程读终端停止进程
SIGTTOU后台进程写终端停止进程
SIGUSR1用户自定义信号1终止进程
SIGUSR2用户自定义信号2终止进程
SIGPOLLI/O事件发生终止进程
SIGPROF进程运行时间超过时钟周期终止进程
SIGSYS非法系统调用终止进程
SIGTRAP跟踪/断点发生终止进程
SIGURG紧急数据到达套接字忽略
SIGVTALRM虚拟定时器超时终止进程
SIGXCPU进程超过CPU时限终止进程
SIGXFSZ文件大小超过限制终止进程
SIGWINCH窗口大小发生改变忽略
SIG_BLOCK阻塞指定的信号
SIG_UNBLOCK解除对指定信号的阻塞
SIG_SETMASK设置阻塞信号的掩码

3.3 信号屏蔽

有时候,我们不希望在某段代码执行期间被某些信号中断。可以使用系统调用sigprocmask()来设置信号屏蔽,从而阻塞某些信号的传递。被屏蔽的信号会在sigprocmask()被调用后暂时被阻塞,直到解除屏蔽为止。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小羊客栈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值