linux操作系统之竞态条件(时序竞态)

(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)总结

           竞态条件和系统负载有很紧密的关系,体现出信号的不可靠性。针对于这种情况,应提早预见,主动规避。             

猜你喜欢

转载自blog.csdn.net/xx18030637774/article/details/82262436