信号集

信号集操作相关函数

概念

未决信号集
没有被当前进程处理的信号
阻塞信号集
将某个信号放到阻塞信号集,这个信号就不会被进程处理
阻塞解除之后,信号被处理
自定义信号集

相关函数

int sigemptyset(sigset_t *set); 将set集合置空
int sigfillset(sigset_t *set); 将所有信号加入set集合
int sigaddset(sigset_t *set,int signo); 将signo信号加入到set集合
int sigdelset(sigset_t *set,int signo); 从set集合中移除signo信号
int sigismember(const sigset_t *set,int signo); 判断信号是否存在
sigprocmask函数 屏蔽and接触信号屏蔽, 将自定义信号集设置给阻塞信号集
	                	int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
sigpending – 读取当前进程的未决信号集
                                 int sigpending(sigset_t *set);
                                参数: set -- 内核将未决信号集写入set

信号函数

siganl函数

 typedef void (*sighandler_t)(int);
 sighandler_t signal(int signum, sighandler_t handler);
测试代码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <signal.h>

void myfunc(int sig)
{
    printf("cathc you signal: %d\n", sig);
}

int main(int argc, const char* argv[])
{
    // 注册信号捕捉函数
    signal(SIGINT, myfunc);

    while(1)
    {

    }
    return 0;
}
测试结果

在这里插入图片描述

sigaction函数

 函数原型: 
	int sigaction(int signum,  // 捕捉的信号
		const struct sigaction *act,
            struct sigaction *oldact
       );
	 struct sigaction {
	          void     (*sa_handler)(int);
	          void     (*sa_sigaction)(int, siginfo_t *, void *);
	          sigset_t   sa_mask;
				 在信号处理函数执行过程中,临时屏蔽指定的信号
	          int        sa_flags;
			   0 - sa_handler
	          void     (*sa_restorer)(void);
	  };
测试代码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <signal.h>

void myfunc(int sig)
{
    printf("hello signal: %d\n", sig);
    sleep(5);
    printf("wake up .....\n");
}

int main(int argc, const char* argv[])
{
    // 注册信号捕捉函数
    struct sigaction act;
    act.sa_flags = 0;
    act.sa_handler = myfunc;
    // 设置临时屏蔽的信号
    sigemptyset(&act.sa_mask);  // 0
    // ctrl + 反斜杠
    sigaddset(&act.sa_mask, SIGQUIT);

    sigaction(SIGINT, &act, NULL);

    while(1);

    return 0;
}

测试结果

在这里插入图片描述

SIGCHLD信号

产生的条件
	a. 子进程结束的时候
	b. 子进程挂起
	c. 子进程重新恢复运行状态
使用该信号回收子进程
使用时的注意事项

进程创建的时候, 父子进程共享
阻塞信号集
信号的处理动作
极端问题
1) 父进程信号处理函数注册成功之前,子进程死亡
2) 解决思路:
a) 先将SIGCHLD信号阻塞
b) 父进程的信号处理函数注册成功之后, 解除阻塞

测试

设置阻塞信号集并把所有常规信号的未决状态打印至屏幕
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <signal.h>

int main(int argc, const char* argv[])
{
    // 自定义信号集
    sigset_t myset, old;
    // 清空 -》 0
    sigemptyset(&myset);
    // 添加要阻塞的信号
    sigaddset(&myset, SIGINT);
    sigaddset(&myset, SIGQUIT);
    sigaddset(&myset, SIGKILL);

    // 自定义信号集设置到内核中的阻塞信号集
    sigprocmask(SIG_BLOCK, &myset, &old);

    sigset_t pend;
    int i = 0;
    while(1)
    {
        // 读内核中的未决信号集的状态
        sigpending(&pend);
        for(int i=1; i<32; ++i)
        {
            if(sigismember(&pend, i))
            {
                printf("1");
            }
            else if(sigismember(&pend, i) == 0)
            {
                printf("0");
            }
        }
        printf("\n");
        sleep(1);
        i++;

        // 10s之后解除阻塞
        if(i > 10)
        {
//           sigprocmask(SIG_UNBLOCK, &myset, NULL);
           sigprocmask(SIG_SETMASK, &old, NULL);
        }
    }
    return 0;
}

测试结果

在这里插入图片描述

setitimer函数测试源码

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>

void myfunc(int sig)
{
    printf("hello\n");
}

int main(int argc, const char* argv[])
{
    struct itimerval new_value;
    new_value.it_interval.tv_sec = 1;
    new_value.it_interval.tv_usec = 0;

    new_value.it_value.tv_sec = 2;
    new_value.it_value.tv_usec = 0;

    signal(SIGALRM, myfunc);
    setitimer(ITIMER_REAL, &new_value, NULL);
    while(1)
    {
    }
    return 0;
}




测试结果

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值