信号的基本概念和操作

目录

1、信号的概念

2、如何查看

3、分类

4、标准信号的默认行为

5、特点

6、产生信号

7、注册信号行为

8、等待信号的到来

9、信号集

10、信号屏蔽字

11、重入

12、练习


1、信号的概念

                又叫软中断,可以通过函数/按键产生。

2、如何查看

                kill -l
                man 7 signal

3、分类

                1. 标准信号(1~31)
                2. 实时信号(34~64)

4、标准信号的默认行为

                TERM    接收到信号的进程终止
                CORE    接受到信号的进程终止并产生dump文件
                IGN        接受到信号的进程忽略
                STOP     接受到信号的进程暂停
                CONT    接受到信号的暂停的进程继续

5、特点

                1. 丢失
                2. 会打断阻塞的系统调用
                3. 同一个信号不会嵌套相应---》执行信号处理函数期间mask置1了
                4. 不能在信号处理函数中进程longjmp跳转
                5. 如何忽略一个信号? mask置1

6、产生信号

                1. 按键 Ctrl+c-->SIGINT      Ctrl+\----SIGQUIT       Ctrl+z--->SIGSTOP
                2. alarm(2)/setitimer(2)---->SIGALRM
                3. kill(2)
                4. 程序段错误

7、注册信号行为

#include <signal.h>

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

        signum:指定的信号,可以为除SIGKILL 及SIGSTOP外的任何信号
        act:       信号处理方式
        oldact:  旧的信号处理方式 将存储到此指针指向的结构体
        结构体类型如下:                可参考Linux——信号处理函数sigaction()

struct sigaction {
    void     (*sa_handler)(int);
    void     (*sa_sigaction)(int, siginfo_t *, void *);
    sigset_t   sa_mask;
    int        sa_flags;
    void     (*sa_restorer)(void);
};

8、等待信号的到来

#include <unistd.h>

int pause(void);

9、信号集

        sigset_t
        sigemptyset(2) 空集
        sigfullset(2) 满集
        sigaddset(2)  将指定信号加入到集合
        sigdelset(2)  将信号从集合中移除

#include <signal.h>

int sigemptyset(sigset_t *set);

int sigfillset(sigset_t *set);

int sigaddset(sigset_t *set, int signum);

int sigdelset(sigset_t *set, int signum);

10、信号屏蔽字

#include <signal.h>

/* Prototype for the glibc wrapper function */
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

可参考sigprocmask详解

11、重入

        第一次调用还没结束,就发生了第二次调用
        信号处理函数极可能发生重入,两个信号注册了同一个信号处理函数

12、练习

        1、使用sigaction函数注册信号,调用屏蔽函数屏蔽2、3号信号

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

/*
 打印每一行*不受2和3信号干扰
 */

static void sig_handler(int s);
int main(void)
{
	sigset_t set, oldset;
	struct sigaction act, oldact;

// 	signal(SIGINT, sig_handler);
	act.sa_handler = sig_handler;
	act.sa_flags = 0;
	sigemptyset(&act.sa_mask);
	sigaction(SIGINT, &act, &oldact);
//  signal(SIGQUIT, sig_handler);
	act.sa_handler = SIG_DFL;
	sigaction(SIGQUIT, &act, NULL);

	// 初始化集合
	sigemptyset(&set);
	sigaddset(&set, SIGINT);
	sigaddset(&set, SIGQUIT);

	for (int i = 0; i < 5; i++) {
		// 加入
		sleep(1);
		sigprocmask(SIG_BLOCK, &set, &oldset);
		for (int j = 0; j < 5; j++) {
			write(1, "*", 1);
			sleep(1);
		}
		write(1, "\n", 1);
		// 设置
		sigprocmask(SIG_SETMASK, &oldset, NULL);
	}

	return 0;
}

static void sig_handler(int s)
{
	write(1, "!", 1);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值