(1)时序竞态:前后两次运行同一个程序,出现的结果不同。
(2)pause函数:使用该函数会造成进程主动挂起,并等待信号唤醒,调用该系统调用的进程会处于阻塞状态(主动放弃CPU)
函数原型:int pause(void); 返回值为-1,并设置errno为EINTR
使用pause和alarm实现sleep函数;
(3)时序问题分析
1)如果在执行完函数alarm函数调用时(还没有计时完),此时进程失去cpu,进入就绪等待状态。
2)定时时间到,内核向当前进程发送SIGALRM信号,信号无法被处理,信号处于阻塞等待状态。
3)当进程再次获得cpu资源时,SIGALRM信号被递达,信号捕捉,执行捕捉函数。
4)捕捉函数结束后,返回当前进程主控流程,pause()被调用挂起等待,无法被唤醒。
主要原因:是因为在alarm函数和pause函数之间执行的时间比定时长,导致定时完了还没执行pause函数。
(4)解决方法:使用sigsuspend函数(在严格要求时序的场合下使用)
函数原型:int sigsuspend(const sigset_t *mask)
sigsuspend调用期间,进程信号屏蔽字由参数mask指定。
实现原理:在sigsupend调用之前屏蔽该信号,临时信号屏蔽字mask中解屏蔽这个信号,那么信号来的时候在sigsuspend中是将信号阻塞,在mask中则使用该信号。
(5)总结
竞态条件和系统负载有很紧密的关系,体现出信号的不可靠性。针对于这种情况,应提早预见,主动规避。