【VxWorks系列】任务间同步与通信之信号

VxWorks中的信号是从POSIX沿用过来的概念,如果你熟悉Linux下的signal,那么几乎就是一回事。信号跟信号量,那完全是两回事,信号有点类似事件,不过事件接口是同步的,而信号处理是异步的,所以其实信号更像中断,或可以称为软中断。
先看个简单的例子:
void signalRoute1(int sig)
{
     logMsg("signalRoute1 signal id: %d\n", sig,0,0,0,0,0);
}
void trySignal()
{
     signal(SIGBUS, signalRoute1);
     raise(SIGBUS);
}
在这个例子中,先通过signal方法,绑定信号SIGBUS的处理方法signalRoute1,然后通过raise向当前任务发送信号,信号处理函数被执行。
第一个概念,绑定的信号处理函数是在哪运行,后台新任务中?当前任务中?系统特殊任务中?答案是会在信号目标任务的上下文中运行,所以该例子中因为raise是向当前任务发送信号,所以之后会挂起当前任务的执行,但仍旧在本任务的上下文中响应signalRoute1。
再看一个例子:
void signalRoute2(int sig)
{
     logMsg("signalRoute2 sig id: %d\n", sig,0,0,0,0,0);
}
void taskRoute(void* param)
{
     int task_id = (int)param; 
     kill(task_id, 0x10);
}
void trySignal()
{
     int id = taskIdSelf();
     signal(0x10, signalRoute2);
     taskSpawn("vxSignal", 150, VX_FP_TASK, 30000, (FUNCPTR)taskRoute, id,0,0,0,0,0,0,0,0,0 );
}
先说明下,kill跟rasise一样都是给任务发送信号,但rasise只能给当前任务,而kill可以指定任务发送,指定任务会被挂起,而信号处理就会在任务id指定任务的上下文中运行。

第二个概念,不能向内核任务发送信号,可以给任务本身,系统public的任务或系统任何其他进程(6.x开始支持process)发送信号。

第三个概念,系统中有31个可用的信号(1~31),每个信号都有默认的含义和处理,但用户可以修改默认的设定。

第四个概念,应该在什么时候用信号?信号本身也可以很方便的达成任务间的通信,但是正常情况下我们应该尽量少用信号,为什么?因为信号会破坏既有处理的优先级控制。因为信号是异步处理的,所以很难避免在信号处理导致目标任务挂起时,是否会因为该任务锁定了某自愿导致正常处理逻辑被破坏,通俗点说就是信号处理很可能阻塞正常的逻辑。所以一般只有在错误处理或者异常等优先级相对很高的处理上使用信号。

第五个概念,即使任务处于挂起状态(比如等待某信号量),发送信号时还是可以触发该任务。

第六个概念,信号处理函数有何需要注意的?因为第四点中提到的问题,所以信号处理函数应该尽量保证处理短小,精简,不使用会导致阻塞的处理。其实有点类似中断的处理,关于这点可以参考我另一篇文章:《【VxWorks系列】中断服务程序中哪些可以做哪些不可以做》。

总结一下,对于常规的任务间通信,往往前几篇中提到的几种方式更合适,更通用,更安全。而对于信号,一般更多的被使用在错误处理或异常中,总之还是慎用。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值