组合键 发送指定信号_给使用设备的进程发信号

今天评审一个方案的时候看到有人用到file_operations->fasync()加kill_fasync()的组合来处理设备异常的时候给进程发信号的问题。我对这个设计的语义不太了解,所以通过本文来调查一下相关概念。

本分析基于5.1主线Linux内核。

fasync这个回调是在ioctl(FIOASYNC(FASYNC))的时候用的(参见fs/ioctl.c:ioctl_fioasync),相当于用户态调用了fcntl()并修改了O_ASYNC标记。

回调的实现要求是调用fasync_helper()初始化一个async_struct,然后等到有东西需要汇报给用户态的时候,调用kill_fasync(async_struct, SIGXXX, POLL_XXX)把不同类型的信号发送给锁指定的进程(默认用SIGIO,从这个信号的选择上,也可以看到这个设计的主要意图)。另外,fcntl(F_SETOWN_XX)可以指定接收信号的进程,一般是进程组的组长(不是随便给一个都可以的,不是本组的进程是肯定不行的。这一点,不看代码,从Unix的权限管理上就可以推断)。

而且这个接口并非主流:Linux_5.1 - Linux Kernel Newbies,已经有新方案在取代它了。在这个介绍中也专门说了,这个接口只能配合O_DIRECT标记协同使用,并不能用于广泛的情形。

把这个逻辑一组合,就可以知道,这个功能本质就是提供异步IO的:你通过fcntl()设定要求AIO,然后不用使用read/write,poll,select了,主线程直接执行你其他的业务流,等有数据的时候,系统通过发信号来通知你。这基本上可以认为是用于非密集IO的。我设想主要场景是:比如你有一个温度传感器,大部分时间都不用去读它的数据的,你只是处理你的主业务,在Socket上收发什么的,除非温度改变,你需要看看现在温度是多少,才接收一个信号,更新一下,然后就回去继续处理你的主业务了。所以,这个功能用于O_DIRECT才没有什么违和。而io_uring才是正经解决大数据流的。

换句话说,fasync这个功能啊,确实有很多硬件通过它给用户进程发信号,但这个其实是用户进程主动要求的,如果用户进程没有主动要求(调用fcntl让你创建async_struct),这种方法根本无法直接把信号发出去。

所以,如果你是要在设备异常的时候直接强制相关用户进程处理或者退出,还是只能用send_sig_info()或者force_sig_info()来发送。

所以,我们做设计写代码,不要看见风就是雨,看见有个signal拿起来就用,能跑就完事,这样设计跑不了几步的。设计工作大部分时间不是写代码,而是调查啊。

(在这个专栏里面放这么多实操的东西,也是希望读者可以看到,我们说的玄而又玄的所谓设计,所谓构架,所谓语义,都是非常具体和解决实际问题的,不是你把代码拷贝上来,然后说两句高大上的废话那种就叫设计。这个例子中我可一行代码没写,但我一下就干掉了上百行代码,预期这个设计继续下去,还有在未来影响数千上万行代码,你还能说“设计”不重要,主要靠堆人力编码就可以了吗?)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值