- 前言
- 一、sleep无法正常休眠
- 二、接收到信号但是配置文件没有更新
- 总结
前言
这片文章会持续更新在信号使用中遇到的bug:
一、sleep无法正常休眠
- 问题描述:
再给后端的cpld发送命令,之后延时2s(sleep(2))读取cpld的特殊寄存器的数据,但总是错误的。但是使用两个sleep(2),就可以读取正确。即使第一个延时100s,不使用第二个sleep也不能正确读取。write() sleep(100) sleep(2) read()
- 问题原因
经过实验,从sleep(100)处返回时间还剩1s,也就是sleep(2)恰好不能被延时2s,提前收到信号中断返回了。再执行第二次sleep时,没有了信号,可以正常睡眠。 - 解决办法
为了避免这种情况,可以根据sleep的返回值,重新定义一个休眠函数,从而达到真正的睡眠时间。unsigned int time = 2; do{ time = sleep(time) }while(time > 0);
- 深入理解sleep函数
信号【3】- 理解sleep函数
-
问题描述:
在项目中遇到一个问题:在设备信号线插拔测试的时候,信号线拔下来了,但是前端网页的状态并没有更新。以下是项目中的伪代码。进程:1 void handler(int num) { flag = 1; } int main(){ sigset_t prevMask,intMask; struct sigaction sa; sigemptyset(&intMask); sigaddset(&intMask,SIGINT); sigemptyset(&prevMask); sa.sa_flags = 0; sa.sa_handler = handler; sigaction(SIGMIN,&sa,NULL); while(1){ if(flag){ sigprocmask(SIG_BLOCK,&intMask,&prevMask); /*以下为不希望被SIGMIN打断的关键代码*/ flag = 0; read(fd,buff,128); prase(buff); update(json.config) /*end 关键代码*/ /*恢复旧的掩码解除对SIGMIN的阻塞*/ sigprocmask(SIG_BLOCK,&prevMask,NULL); } pause();/*本意是希望进程能进入暂停状态,释放CPU资源,等待信号唤醒,继续执行*/ } }
-
问题原因
经过分析是,一旦第二次调用sigprocmask之后被阻塞的未决信号立即被传递,执行了信号处理函数,发送在pause之前,那么一旦进入pause则进程被阻塞,直到第二个实例到达为止。从而不能再执行文件更新的事件。
这段代码本意是:解除对SIGMIN的阻塞并等待其第一次出现。 -
解决办法
为了避免这种情况,使用了sigsuspend的函数,将阻塞和挂起封装成一个原子 *** 作。进程:2 void handler(int num) { flag = 1; } int main(){ sigset_t prevMask,intMask; struct sigaction sa; sigemptyset(&intMask); sigaddset(&intMask,SIGINT); sigemptyset(&prevMask); sa.sa_flags = 0; sa.sa_handler = handler; sigaction(SIGMIN,&sa,NULL); while(1){ if(flag){ sigprocmask(SIG_BLOCK,&intMask,&prevMask); /*以下为不希望被SIGMIN打断的关键代码*/ flag = 0; read(fd,buff,128); prase(buff); update(json.config) /*end 关键代码*/ /*恢复旧的掩码解除对SIGMIN的阻塞*/ sigsuspend(NULL);/*原子 *** 作*/ sigprocmask(SIG_BLOCK,&prevMask,NULL); } } }
-
深入理解sigsuspend函数
信号【5】-理解sigsuspend
总结
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)