UNIX环境高级编程读书笔记(十)—信号 (5)

本文详细解析了Linux内核中的进程信号管理函数sigsuspend和sigsetjmp/siglongjmp的原理、使用场景及具体实现流程。通过代码示例展示了如何在特定代码段前暂停进程执行,直至接收到特定信号,以及如何在不同上下文间保存和恢复信号屏蔽状态,以实现复杂的应用场景。深入理解这些函数对于构建稳定、高效的并发程序至关重要。

11.

名称::

sigsuspend

功能:

 

头文件:

#include <signal.h>

函数原形:

int sigsuspend(const sigset_t *sigmask);

参数:

sigmask 要替换的进程信号屏蔽字。

返回值:

-1,errno设置为EINTR.

sigsuspend用于在接收到某个信号之前, 临时用sigmask替换进程的信号掩码, 并暂停进程执行,直到收到信号为止。sigsuspend 返回后将恢复调用之前的信号掩码。信号处理函数完成后,进程将继续执行。该系统调用始终返回-1,并将errno设置为EINTR。

       但要注意的是,sigsuspend的整个操作都是原子的,也就不允许被打断的。sigsuspend的整个原子操作过程为:

              (1) 设置新的mask阻塞当前进程;

              (2) 收到信号,恢复原先mask;

              (3) 调用该进程设置的信号处理函数;

              (4) 待信号处理函数返回后,sigsuspend返回。

       这种技术的功能有:

       1.可以保护不希望由信号中断的代码临界区。

       2.等待一个信号处理程序设置一个全局变量。

       3.实现父子进程之间的同步。

      

       这个函数的执行步骤有点难理解,但我们仔细分析一下就会明白,sigsuspend函数是先用我们定义的sigmask来暂时替代信号屏蔽集,然后阻塞当前进程,收到信号时调用信号处理函数函数对信号进行处理,处理后返回。

       下面是函数的一个例子:

/*10_10.c*/

#include <signal.h>

#include <stdio.h>

#include <stdlib.h>

 

static void sig_int(int);

 

int main(void)

{

sigset_t newmask,oldmask,zeromask;

if(signal(SIGINT,sig_int)==SIG_ERR) /*设置信号处理,调用信号处理函数*/

    perror(“signal error”);

sigemtyset(&zeromask); /*初始化zeromask信号集*/

sigemtyset(&newmask); /*初始化newmask信号集*/

if(sigprocmask(SIG_BLICK,&newmask,&oldmask)<0) /*把信号集newmask设置为信号屏蔽集*/

    perror(“SIG_BLOCK error”);

printf(“In critical region: SIGINT\n”);

if(sigsuspend(&zeromask)!=-1) /*用zeromask代替信号屏蔽集,然后阻塞信号,如果有信号来通过signal调用处理函数,最后返回*/

    perror(“sigsuspend error”);

printf(“After return from sigsuspend: SIGINT\n”);

sleep(5);

 

exit(0);

}

 

static void sig_int(int signo) /*信号处理函数

{

printf(“In sig_int: SIGINT\n”);

}

 

       程序先打印In critical region: SIGINT,然后执行sigsuspend阻塞信号,当用户按“ctrl+c”时进程通过signal调用信号处理函数sig_int打印In sig_int: SIGINT,返回后打印After return from sigsuspend: SIGINT。然后程序休眠5秒钟,在这5秒钟如果用户按“ctrl+c”进程是不会有反应的,因为调用完sigsuspend进程就恢复了原先的屏蔽集。而原先的屏蔽集屏蔽了SIGINT信号。

12.

名称::

sigsetjmp/siglongjmp

功能:

save stack context for non-local goto

头文件:

#include <setjmp.h>

函数原形:

int sigsetjmp(sigjmp_buf env,int savemask);

void siglongjmp(sigjmp_buf env,int val);

参数:

 

返回值:

若直接调用则为0,若从sigsetjmp调用返回则为非0。

这两个函数和setjmp,longjmp之间的唯一区别是sigsetjmp增加了一个参数。如果savemask非0,则sigsetjmp在env中保存进程的当前信号屏蔽字。调用siglongjmp时。如果带非0 savemask的sigsetjmp调用已经保存了env,则siglongjmp从其中恢复保存的信号屏蔽字。

在车辆工程中,悬架系统的性能评估和优化一直是研究的热点。悬架不仅关乎车辆的乘坐舒适性,还直接影响到车辆的操控性和稳定性。为了深入理解悬架的动态行为,研究人员经常使用“二自由度悬架模型”来简化分析,并运用“传递函数”这一数学工具来描述悬架系统的动态特性。 二自由度悬架模型将复杂的车辆系统简化为两个独立的部分:车轮和车身。这种简化模型能够较准确地模拟出车辆在垂直方向上的运动行为,同忽略了侧向和纵向的动态影响,这使得工程师能够更加专注于分析与优化与垂直动态相关的性能指标。 传递函数作为控制系统理论中的一种工具,能够描述系统输入和输出之间的关系。在悬架系统中,传递函数特别重要,因为它能够反映出路面不平度如何被悬架系统转化为车内乘员感受到的振动。通过传递函数,我们可以得到一个频率域上的表达式,从中分析出悬架系统的关键动态特性,如系统的振幅衰减特性和共振频率等。 在实际应用中,工程师通过使用MATLAB这类数学软件,建立双质量悬架的数学模型。模型中的参数包括车轮质量、车身质量、弹簧刚度以及阻尼系数等。通过编程求解,工程师可以得到悬架系统的传递函数,并据此绘制出传递函数曲线。这为评估悬架性能提供了一个直观的工具,使工程师能够了解悬架在不同频率激励下的响应情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值