c语言信号集与信号屏蔽

什么是信号集:

  • 是一种专门用于存储多个信号的数据类型sigset_t

  • 该类型占128字节,每个字节代表了一种信号的有或无

int sigemptyset(sigset_t *set);
功能:将信号集set中的所有信号置0 清空信号集
​
int sigfillset(sigset_t *set);
功能:把信号集set中所有信号置1
​
int sigaddset(sigset_t *set, int signum);
功能:将信号集set中的信号signum置1
​
int sigdelset(sigset_t *set, int signum);
功能:将信号集set中的信号signum置0
​
int sigismember(const sigset_t *set, int signum);
功能:测试信号集中是否存在信号signum
返回值:存在返回1,不存在返回0,非法信号返回-1
#include <stdio.h>
#include <signal.h>
​
int main(int argc,const char* argv[])
{
    sigset_t set;
    
    sigfillset(&set);
    sigemptyset(&set);
​
    sigaddset(&set,2);
    sigaddset(&set,7);
    for(int i=1;i<=128;i++)
    {   
        printf("信号%d 状态:%d\n",i,sigismember(&set,i));
    }   
}              
                                                                 

信号的递送与未决:

  • 当信号产生后,系统内核会在其内部维护的进程表中,给响应信号的进程设置一个对应的标志位,这整个过程称为信号的递送

  • 当信号产生到完成递送之间会存在一段时间间隔,处于这个时间间隔的信号状态是”未决“

信号屏蔽:

  • 每个进程都有一个信号掩码(signal mask,就是一个信号集),其中存在的信号是需要被该进程屏蔽的信号

  • 让需要屏蔽的信号处于未决状态,当可以接受信号时,让其退出未决状态完成递送

  • 当执行一些特殊的且不想被干扰中断的操作时,例如:更新数据库敏感操作,此时可以把信号放入信号屏蔽集中,等操作完成后,再从信号屏蔽集中删除,继续处理信号,保证敏感操作的安全性

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
功能:修改当前进程的信号掩码(屏蔽集)
how:修改信号掩码的方式
    SIG_BLOCK       将set中的信号加入到信号掩码中
    SIG_UNBLOCK     从信号掩码中把set中的信号删除
    SIG_SETMASK     把set中的信号替换掉信号掩码的所有信号
set:信号集 用于设置
oldset:信号集 用于获取旧信号集 NULL则不获取
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
void sigint(int num)
{
    printf("按下了ctrl+c\n");
​
}
void sigrtmin(int num)
{
    printf("我可靠!\n");
}
int main(int argc,const char* argv[])
{
    signal(SIGINT,sigint);
    signal(34,sigrtmin);
​
    sigset_t set,oldset;
    sigemptyset(&set);
    
    // 给信号集添加信号
    sigaddset(&set,SIGINT);
    sigaddset(&set,34);
​
    // 设置信号屏蔽
    sigprocmask(SIG_BLOCK,&set,&oldset);
​
    printf("我是进程%u\n",getpid());
    sleep(15);
    printf("我醒了,解除屏蔽\n");
​
    // 屏蔽解除
    sigprocmask(SIG_SETMASK,&oldset,NULL);
    for(;;);
}

对于可靠和不可靠信号屏蔽的信号:

  • 对于不可靠信号,通过信号屏蔽该信号后,在信号屏蔽期间,该信号产生多次,都只会被屏蔽第一个,只有第一个处于未决,剩余的都不参与排队直接忽略,当解除屏蔽后,只会有第一个不可靠信号被完成递送

  • 相反,对于所有在屏蔽期间产生的可靠信号,都会排队变成未决,当屏蔽解除后,会按照次序全部完成递送

带参的信号发送与捕获

  • 可以让不同进程之间发送信号时,带上一些简易的数据,完成不同进程之间简单通信,这叫带参数的信号发送

int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
功能:能够设置带参数的信号处理函数方案

计时器

系统为每个进程维护三个计时器:
  • 真实计时器:进程运行的实际时间

  • 虚拟计时器:进程运行在用户态所消耗的时间

  • 实用计时器:是进程在用户态和内核态消耗的时间之和

实际真正的时间(真实计时器) =用户态时间+内核时间+睡眠时间+状态切换耗时

通过设置计时器的起始时间和重复间隔时间给进程设置定时事件,例如定时保存、定时上传操作。

获取\设置定时器
#include <sys/time.h>
​
int getitimer(int which, struct itimerval *curr_value);
功能:获取当前进程的某个定时器的定时方案
    
int setitimer(int which, const struct itimerval *new_value,struct itimerval *old_value);
功能:设置当前进程的定时方案
    
which:指定哪个计时器
    ITIMER_REAL     真实计时器       SIGALRM(14)
    ITIMER_VIRTUAL  虚拟计时器       SIGVTALRM(26)
    ITIMER_PROF     实用计时器
    
struct itimerval {
    struct timeval it_interval; //  间隔时间,定时器开始后,每间隔这个时间就会再发出一次定时器信号,一直重复
    struct timeval it_value;    //  开始时间,从该时间开始发送第一个定时器信号
}
​
struct timeval {
    time_t      tv_sec;         // 秒数
    suseconds_t tv_usec;        // 微秒,不能超过10^6
}
​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值