mysleep

Posted Luella_G

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysleep相关的知识,希望对你有一定的参考价值。

一、普通版本的mysleep函数

1.main函数调用mysleep函数,后者调用sigaction注册了SIGALRM信号的处理函数handler。 
2.调用alarm(timeout)设定闹钟。 
3.调用pause等待,内核切换到别的进程运行。 
4.timeout秒之后,闹钟超时,内核发SIGALRM给这个进程。 
5.从内核态返回这个进程的用户态之前处理未决信号,发现有SIGALRM信号,其处理函数是handler。 
6.切换到用户态执行handler函数,进入handler函数时SIGALRM信号被自动屏蔽, 从handler函数返回时SIGALRM信号自动解除屏蔽。然后自动执行系统调用sigreturn再次进入 内核,再返回用户态继续执行进程的主控制流程(main函数调用的mysleep函数)。 
7.pause函数返回-1,然后调用alarm(0)取消闹钟,调用sigaction恢复SIGALRM信号以前的处理动作。

代码实现:

#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>

void handler(int signum)


int mysleep(int time)

    struct sigaction act,oldact;
    act.sa_handler = handler;
    int sa_flags = 0;
    sigset_t sa_mask;
    sigemptyset(&sa_mask);
    sigaction(SIGALRM, &act, &oldact);
    alarm(time);
    pause();
    int ret = alarm(0);
    sigaction(SIGALRM, &act, NULL);
    return ret;


int main()

    while(1)
    
        mysleep(1);
        printf("I am sleeping!!\\n");
    
    return 0;
运行结果:


二、规避竞态条件的mysleep函数

1.屏蔽SIGALRM信号; 
2.alarm(time); 
3.解除对SIGALRM的屏蔽; 
4.pause(); 

代码实现:

#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>

void handler(int signum)


int mysleep(int time)

    struct sigaction act,oldact;
    act.sa_handler = handler;
    int sa_flags = 0;
    sigset_t sa_mask, oldmask, suspmask;
    sigaction(SIGALRM, &act, &oldact);
    sigemptyset(&sa_mask);
    sigaddset(&sa_mask, SIGALRM);
    sigprocmask(SIG_BLOCK, &sa_mask, &oldmask);
    alarm(time);
    suspmask = oldmask;
    sigdelset(&suspmask, SIGALRM);
    sigsuspend(&suspmask);
    int ret = alarm(0);
    sigaction(SIGALRM, &act, NULL);
    sigprocmask(SIG_SETMASK, &oldmask, NULL);
    return ret;


int main()

    while(1)
    
        mysleep(1);
        printf("I am sleeping!!\\n");
    
    return 0;
运行结果:


以上是关于mysleep的主要内容,如果未能解决你的问题,请参考以下文章