浅谈对于信号函数signa();的理解

记录学习过程


前言

我们都知道,在调用信号处理函数时,signal函数的定义是这样的:

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

在初步的学习中,虽然能够了解怎么使用该函数,但对于我这种菜鸟来说,其实也只学会了用,而没有去真正理解该函数。遂深究,谨以此篇记录学习的过程和思路。


一、signal();函数的使用

signal函数相当于系统的“软中断”,其包含的信号处理有三种:忽略、捕捉和默认动作。

我们都知道,signal函数包含两个参数,一个是整型的信号编号,一个是指向用户定义的信号处理函数的指针,在调用signal函数时,我们只需要将其“填满”,就可实现调用的目的。

二、对于signal函数的理解

那么,signal函数到底是如何运作的呢?

这里要先对比两个定义:

int *g();
int (*g)();

根据运算优先级,()的优先级大于*,故可知int *g();为一个函数,该函数的返回值为一个指向int型的指针,而int (*g)();则理解为:一个函数指针,该函数指针指向的函数的返回值为int型。

所以,当我们要定义一个返回值为int,形参为int型的函数指针时,函数就会变成:int (*g)(int)

当我们能够理解前置函数定义时,signal函数也变得便于理解。

我们回过头来看signal函数的定义:

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

首先得理解这边的typedef是怎么用的,这很重要。

在定义指针时,我们往往会用到一种操作,叫做强制类型转换,我们会将指针转换为我们想要它指向的类型,例如:strcut name* a =(struct name*)p;

该例子将p指针强制转换为结构体指针。同样的,如果我们要强制转换一个指针使其指向返回值为void类型且形参为int型的函数指针时,我们的操作为:void(*)(int);

根据这个,在这里的typedef就应该理解为:将强制转换一个指针使其指向返回值为void类型且形参为int型的函数指针的操作,命名为sighangdler_t

理解了这个,我们把typedef去掉,将signal函数的定义复杂化来看:(其实这一步不好理解)

void(*signal(int signum,void(*)(int)))(int);

怎么理解这个函数?

首先,通过查阅man手册我们知道,signal函数最终需要指向用户自己定义的一个处理信号的函数。那么,signal函数的返回值就必须是一个指向viod类型的函数指针,我们忽略signal函数的形参,则按照前面所说,应将函数写成void(*signal(形参))(int);

之后,我们再带上形参,也就是signal(int signum,viod(*)(int)),不难理解,signal需要两个参数来完成调用,一个形参是int型的整型信号编号,一个是指向用户定义的信号处理函数的指针。有了这两个参数,signal即可完成其相应的任务,去执行相应的操作。


总结

该篇只是讲了signal函数的用法规则以及对于其定义的理解,并不涉及signal函数自身是如何设计,欢迎各位指正。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值