信号深入学习(下)

简介: 信号深入学习(下)

alarm函数

设置定时器(闹钟)。在指定seconds后,内核会给当前进程发送 14 SIGALRM信号。进程收到该信号,默认动作终止

 #include 
 unsigned int alarm(unsigned int seconds);

返回值:
上次定时剩余时间
无错误现象
定时,与进程状态无关(自然定时法)!就绪,运行,终止,挂起(阻塞,暂停),僵尸…无论进程处于何种状态,alarm都会计时。
eg: 编写程序测试你使用的计算机1秒能数对多少个数。

#include
#include
#include
#include
#include
int main()
{
   
   int i=0;
   alarm(1);
   while(1)
   printf("%d\n",i++);
   return 0;
}

time命令可以查看程序执行的时间
实际执行时间=系统时间+用户时间+等待时间
在这里插入图片描述

setitimer函数

setitimer函数为设置定时器(闹钟),可替代alarm函数,比alarm函数精确度更高,精度为微秒,可以实现周期定时。

函数头文件为 #include
函数原型为 int setitimer(int which,const struct itimerval *new_value,struct itimerval *old_value);

返回值
成功返回 0
失败返回 -1 error
参数

which:指定定时方式
1.自然定时:ITIMER_REAL 计算自然时间
2.虚拟空间记时(用户空间):ITIMER_VIRTUAL 只计算进程占cpu的时间
3.运行时记时(用户+内核):ITIMER_PROF 计算占用cpu及系统调用的时间
old_value:上次定时剩余时间
new_value:新计时时间

struct itimerval 结构体

 struct itimerval {
   
               struct timeval it_interval; /* Interval for periodic timer */
               struct timeval it_value;    /* Time until next expiration */
           };

           struct timeval {
   
               time_t      tv_sec;         /* seconds */
               suseconds_t tv_usec;        /* microseconds */
           };

在这里插入图片描述eg : 编写程序测试你使用的计算机1秒能数对多少个数

#include
#include
int main()
{
   
    int i=0;
    struct itimerval new_t;
    struct itimerval old_t;
    new_t.it_interval.tv_sec=0;//周期定时  //秒
    new_t.it_interval.tv_usec=0;         //微妙
    new_t.it_value.tv_sec=1;//定时时长    //秒
    new_t.it_value.tv_usec=0;           //微妙
    if(setitimer(ITIMER_REAL,&new_t,&old_t)==-1)
    {
   
        perror("setitimer error");
        return -1;
    }
    while(1)
    printf("%d\n",++i);
    return 0;
}

信号集操作函数

自定义信号集操作函数

#include 

       int sigemptyset(sigset_t *set);  //清空信号集,全置为零

       int sigfillset(sigset_t *set); //填满信号集 ,全置为一

       int sigaddset(sigset_t *set, int signum); //将一个信号添加到信号集中

       int sigdelset(sigset_t *set, int signum);//将一个信号从信号集中移除

       int sigismember(const sigset_t *set, int signum);
       //判断一个信号是否在信号集合中(在返回1,不在返回0)

设置信号屏蔽字和解除屏蔽

    int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

参数:
how

SIG_BLOCK
设置阻塞

SIG_UNBLOCK
取消阻塞

SIG_SETMASK
用自定义set替换mask

set

自定义set

oldset

旧有的mask

查看未决信号集

  int sigpending(sigset_t *set);

set :传出的未决信号集
eg: 练习阻塞SIGNIT信号并查看

#include
#include
void print(sigset_t set)
{
   
    int i=0;
    for(i=0;i<32;i++)
    {
   
        if(sigismember(&set,i))
        putchar('1');
        else
        putchar('0');
    }
    printf("\n");
}
int main()
{
   
    sigset_t set;
    sigset_t oldset;
    sigset_t pedset;
    sigemptyset(&set);
    sigaddset(&set,SIGINT);
    sigprocmask(SIG_BLOCK,&set,&oldset);
    sigpending(&pedset);
    print(pedset);
    while(1);
    return 0;
}

信号捕捉

signal函数

注册一个信号捕捉函数

 #include 

 typedef void (*sighandler_t)(int);  //函数指针

 sighandler_t signal(int signum, sighandler_t handler);

eg:

#include
#include
void sig_catch(int signo)
{
   
    printf("catch you ! %d\n",signo);
} 
int main()
{
   
    signal(SIGINT,sig_catch);
    while(1);
    return 0;
}

sigaction函数

修改信号处理动作(通常在Linux用其注册一个信号的捕捉函数)

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

参数:
act : 传入参数,新的处理方式
old: 传出参数,旧的处理方式

 struct sigaction 
 {
   
      void     (*sa_handler)(int);  //捕捉到信号后要干的事情
      void     (*sa_sigaction)(int, siginfo_t *, void *);
      sigset_t   sa_mask;    //只作用于信号捕捉期间
      int        sa_flags;
      void     (*sa_restorer)(void);
 };

eg:捕捉信号SIGINT

#include
#include
#include
void sig_catch(int signo)
{
   
    printf("catch you ! %d\n",signo);
} 
int main()
{
   
    struct sigaction act,oldact;
    act.sa_handler = sig_catch;//set callback function name
    sigemptyset(&act.sa_mask);//清零set mask when sig_catch working
    act.sa_flags=0;            //usually use

    int ret=sigaction(SIGINT,&act,&oldact);
    if(ret==-1)
    {
   
        perror("error");
        exit(1);
    }
    while(1);
    return 0;
}

信号捕捉特性

  • 1)进程正常运行时,默认PCB中有一个信号屏蔽字,假定为☆,它决定了进程自动屏蔽哪些信号。当注册了某个信号捕捉函数,捕捉到该信号以后,要调用该函数。而该函数有可能执行很长时间,在这期间所屏蔽的信号不由☆来指定。而是用sa_mask来指定。调用完信号处理函数,再恢复为☆。
  • 2)XXX信号捕捉函数执行期间,XXX信号自动被屏蔽。
  • 3)阻塞的常规信号不支持排队,产生多次只记录一次。(后32个实时信号支持排队)

测试:

#include
#include
#include
#include
void sig_catch(int signo)
{
   
    printf("catch you ! %d\n",signo);
    sleep(3);

} 
int main()
{
   
    struct sigaction act,oldact;
    act.sa_handler = sig_catch;//set callback function name
    sigemptyset(&act.sa_mask);//清零set mask when sig_catch working
    act.sa_flags=0;            //usually use

    int ret=sigaction(SIGINT,&act,&oldact);
    if(ret==-1)
    {
   
        perror("error");
        exit(1);
    }
    while(1);
    return 0;
}
相关文章
|
机器学习/深度学习 数据采集 数据挖掘
Python 数据分析入门教程:Numpy、Pandas、Matplotlib和Scikit-Learn详解
Python 数据分析入门教程:Numpy、Pandas、Matplotlib和Scikit-Learn详解
573 0
|
3月前
|
负载均衡 安全 Cloud Native
Service Mesh:原则、挑战和演变
服务网格作为云原生架构中的关键组件,旨在解决微服务间通信的复杂性。它通过提供服务发现、负载均衡、安全控制和可观测性等功能,帮助开发者更高效地管理分布式系统。本文探讨了服务网格的起源、核心功能、在多云环境中的应用及其未来发展趋势,展示了其在现代软件架构中的重要价值。
183 10
Service Mesh:原则、挑战和演变
|
5月前
|
网络协议 API
区分TCP/IP、HTTP、Socket三者的差异
HTTP关注于应用层的协议规范,而Socket关注于为应用程序提供编程中的网络功能,这些功能本身是建立在底层的TCP/IP协议之上;HTTP是更高层次的抽象,定义了如何包装数据,而TCP/IP定义了如何传送数据,Socket则是两者之间在程序中的桥梁,负责实现细节。在实际应用中,通常HTTP通信也是通过Socket来完成,因为HTTP仅是具体内容的封装形式,而Socket则是传送方式的实现形式。
530 16
|
6月前
|
API 定位技术 决策智能
通义灵码产品评测报告:智能体赋能编程新时代
本次评测深度体验阿里云通义灵码(Qwen3版本),聚焦其智能体架构、MCP工具集成与记忆能力升级。通过构建天气查询与出行建议微服务,验证其从零搭建项目的能力。评测显示,通义灵码可自动感知环境、调用工具、生成代码,支持3000+ MCP服务一键集成,并具备项目级记忆和风格适应功能。最终实现高效开发闭环,大幅提升生产力。总结其核心优势为智能体自主决策、MCP生态扩展及记忆进化,但仍需优化多智能体协作与兼容性检查等功能。通义灵码重新定义编码助手边界,是开发者“超脑级”搭档。
390 0
|
9月前
|
存储 传感器 缓存
java变量与数据类型:整型、浮点型与字符类型
### Java数据类型全景表简介 本文详细介绍了Java的基本数据类型和引用数据类型,涵盖每种类型的存储空间、默认值、取值范围及使用场景。特别强调了`byte`、`int`、`long`、`float`、`double`等基本类型在不同应用场景中的选择与优化,如文件流处理、金融计算等。引用数据类型部分则解析了`String`、数组、类对象、接口和枚举的内存分配机制。
323 15
|
缓存 NoSQL 关系型数据库
熔断方案
【8月更文挑战第20天】
276 0
|
12月前
|
API
鸿蒙开发:了解显式动画animateTo
在实际的开发中,应该遵循规范,正确的使用属性动画animateTo,切莫在轮询中使用,否则就会造成本不属当前的动画进行执行,造成UI错误,还有一点需要注意,那就是直接使用animateTo可能导致实例不明确的问题,建议使用getUIContext获取UIContext实例,并使用animateTo调用绑定实例的animateTo。
362 3
鸿蒙开发:了解显式动画animateTo
|
存储 开发者
CodeWave智能开发平台--03--目标:应用创建--07供应商数据表格01
CodeWave智能开发平台--03--目标:应用创建--07供应商数据表格01
|
存储 弹性计算 安全
云计算服务选型与成本分析
【7月更文挑战第2天】云计算服务选型与成本分析聚焦企业如何在IaaS、PaaS、SaaS间抉择,考虑云提供商的技术实力、服务范围、成本效益和支持。成本分析涉及硬件、软件和服务成本,通过简单回收期、投资回报率和净现值法评估效益。优化资源配置、弹性伸缩和合理计费是成本控制关键,助力企业高效利用云计算。