Linux进程间通信:信号

信号是linux系统中进程间通信的一种方式, 它是一种异步的通信机制, 用来告诉某个进程, 某种事件已经发生。

系统中信号的默认行为有4种
  1. 终止, 进程停止运行
  2. 忽略, 进程对信号不做任何回应
  3. 停止, 进程暂停运行, 并未停止, 还可以恢复
  4. 继续, 进程从停止的状态恢复运行

用户对信号可以采取自定义操作。

用户对信号可选的自定义操作有3种
  1. 捕捉, 监测到信号时, 对信号行为重定义, 执行用户自定义的函数
  2. 忽略, 检测到信号时, 无论信号的系统默认行为是什么, 都主动忽略
  3. 默认, 检测到信号时, 执行系统默认的信号行为
自定义捕捉信号
/**
 * Description: 捕捉Ctrl + C信号
 * File: signal.c |Time: 2021-05-30 17:31
 */

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

void sig_handler(int signum)
{
	printf("signal [%d] catched.\n", signum);
    printf("Ctrl + c pressed.\n");
    // 发送终止信号终止进程
    kill(getpid(), SIGKILL);
    return ;
}

int main(int argc, const char *argv[])
{
	// 注册一个信号处理程序, 异步信号到来时自动调用sig_handler函数
    signal(SIGINT, sig_handler);

    while(1)
    {
        sleep(1);
    }
    return 0;
}
自定义忽略信号
/**
 * Description: 设置信号发生时, 忽略信号的行为
 * File: signal.c |Time: 2021-05-30 17:31
 */

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

int main(int argc, const char *argv[])
{
    // 选择忽略信号
    signal(SIGINT, SIG_IGN);

    sleep(5);
    kill(SIGKILL, getpid());
    return 0;
}
自定义信号默认行为
/**
 * Description: 设置信号发生时采用系统默认行为
 * File: signal.c |Time: 2021-05-30 17:31
 */

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

int main(int argc, const char *argv[])
{
    // 选择默认的行为
    signal(SIGINT, SIG_DFL);

    while(1)
    {
        sleep(1);
    }
    return 0;
}
不可以自定义其行为的信号
信号常量信号值默认行为说明
SIGKILL9终止不可被忽略
SIGSTOP19暂停不可被忽略
常见的信号
信号常量信号值默认行为说明
SIGHUP1终止在用户终端关闭时产生, 通常是发给和该终端相关联的所有进程
SIGINT2终止在用户输入INTR字符(Ctrl + C)时产生, 内核会发送这个信号到当前终端的所有前台进程
SIGQUIT3终止与SIGINT类似, 但是由QUIT字符(Ctrl + )产生
SIGILL4终止该信号在一个进程企图执行一条非法指令时产生
SIGSEGV11终止该信号在非法访问内存时产生, 如野指针, 缓冲区溢出
SIGPIPE13终止当进程往一个没有读端的管道中写入时产生, 代表“管道破裂”
SIGKILL9终止结束进程, 并且不能被捕捉和忽略
SIGCHLD17忽略子进程退出向父进程发送此信号
SIGSTOP19暂停进程暂停进程, 并且不能被捕捉和忽略
SIGTSTP20暂停进程暂停进程, 用户输入SUSP字符(Ctrl + Z)时产生
SIGCONT18继续运行该信号让进程进入运行态
SIGALRM14终止该信号用于通知进程定时器时间已到
SIGUSR110终止该信号保留给用户进程使用, 系统不会自动产生
SIGUSR213终止该信号保留给用户进程使用, 系统不会自动产生
信号相关的函数接口
kill 发送信号
/**
 * Description: 发送一个信号
 * File: signal.c |Time: 2021-05-30 17:31
 */

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

int main(int argc, const char *argv[])
{
    pid_t pid = getpid();
    // 3秒后发送一个信号杀掉自己
    sleep(3);
    kill(pid, SIGKILL);

    return 0;
}
pause 阻塞等待一个信号到来
  1. pause会使一个进程进入无限期休眠状态, 直到一个信号来将它唤醒
  2. 唤醒pause的信号必须是默认终止进程类型的信号, SIGCHLD 不好使
  3. pause 函数没有成功返回, 只会返回 -1
/**
 * Description: pause函数接口的使用
 * File: signal.c |Time: 2021-05-30 17:31
 */

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

void sig_handler(int signum){}

int main(int argc, const char *argv[])
{
    int i = 0;

    // 过5秒中发送时钟信号
    // 修改时钟信号默认行为, 不执行任何操作
    alarm(5);
    signal(SIGALRM, sig_handler);

    for (i = 0; i < 5; i++)
    {
        // pause会无限期挂起当前进程,直到有信号来唤醒
        // pause只会返回-1
        // 这里模拟, 当程序完成几个任务后进入无限期休眠,
        // 后来时钟信号到来, 唤醒pause, 程序继续运行
        if (i == 2 && -1 == pause())
        {
            perror("pause");
            continue;
        }

        printf("runing something %d ... \n", i);
        sleep(1);
    }

    return 0;
}
raise 给自己发送一个信号
/**
 * Description: raise的使用
 * File: signal.c |Time: 2021-05-30 17:31
 */

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


int main(int argc, const char *argv[])
{
    // 5 秒后会给自己发送一个SIGKILL信号结束自己
    while(1){
        sleep(5);
        raise(SIGKILL);
    }

    return 0;
}
alarm 定时给自己发送一个信号
/**
 * Description: alarm的使用
 * File: signal.c |Time: 2021-05-30 17:31
 */

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


int main(int argc, const char *argv[])
{
    // 5 秒后会给自己发送一个SIGALRM信号结束自己
    alarm(5);
    while(1){
        sleep(1);
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

__万波__

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

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

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

打赏作者

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

抵扣说明:

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

余额充值