12_竞态条件(时序竞态)

/*
    sleep函数几点说明
    1sleep函数作用,让进程睡眠。
    2)能被信号打断,然后处理信号函数以后,就不再睡眠了。直接向下执行代码
    3sleep函数的返回值,是剩余的秒数

*/
//sleep是可被中断的睡眠,但不一定睡够100s
//sleep是可中断的睡眠
void handler(int num)
{
    printf("recv num:%d \n", num);  
    if (num == SIGQUIT)
    {
        //exit(0);
    }
}

#if 1
void test()
{
    int n = 100;
    pid_t   pid;
    printf("main ....begin\n");
    signal(SIGINT, handler);
    sleep(n);  //sleep是可中断睡眠,让进程睡够 
    printf("sleep ....结束\n");
}
#endif
//利用sleep()函数的返回值使程序足够的睡眠
#if 0
void test()
{
    int n = 100;
    printf("main ....begin\n");
    signal(SIGINT, handler);

    //进程醒过来再继续睡,保证睡够100s
    do 
    {
        n = sleep(n);  //sleep是可中断睡眠,让进程睡够 
        if(n != 0){
            printf("还剩余 %d 秒, 要给睡够。。。。。\n", n);
        }else{
            printf("TMD,终于睡醒了。。。。。。\n");
        }
    } while(n > 0);
    printf("sleep ....结束\n");
}
#endif


int main(void)
{

    test();
    return 0;
}
/*
  使用自定义的sleep1()与真正的sleep()的实现。
  但会有3 个问题:
  1)在sleep1()之前调用alarm
  2)程序修改了SIGALRM信号的默认行为
  3)alarm()与pause()之间有竞争条件,若alarm()在调用pause之前超时
  ,并调用了信号处理程序,此时调用pause后,因没有捕捉到其他信号处理函数
  ,造成函数永久被挂起
  解决办法参考apue 339页
*/
#if 1

void  sig_alrm(int signo)
{
    //什么也不做,仅仅是唤醒pause
        printf("收到SIGALRM 信号\n");
}

unsigned int sleep1(unsigned int seconds)
{
    if(signal(SIGALRM, sig_alrm) == SIG_ERR){
        return seconds; 
    }
    printf("set seconds = %d, but 返回值是 %d\n",seconds, alarm(seconds));//开始定时器
    pause();//主动挂起
    return (alarm(0));//关闭定时器,返回剩余的时间
}

void test()
{
    int ret = 0;
    //alarm(3);
    ret = sleep1(7);
    printf("剩余的秒数:%d\n", ret);
}
#endif

int main(void)
{
    test();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/WUZHU2017/article/details/81906182