加入收藏 | 设为首页 | 会员中心 | 我要投稿 佛山站长网 (https://www.0757zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

linux系统编程之信号(六) 竞态条件与sigsuspend函数

发布时间:2013-10-15 09:25:42 所属栏目:Linux 来源:站长网
导读:一、利用pause和alarm函数实现sleep函数 #include unistd.h> int pause(void); pause函数使调用进程挂起直到有信号递达。如果信号的处理动作是终止进程,则进程终止,pause函数没有机会返回;如果信号的处理动作是忽略,则进程继续处于挂起状态,pause不返回
一、利用pause和alarm函数实现sleep函数

#include <unistd.h>

int pause(void);

pause函数使调用进程挂起直到有信号递达。如果信号的处理动作是终止进程,则进程终止,pause函数没有机会返回;如果信号的处理动作是忽略,则进程继续处于挂起状态,pause不返回;如果信号的处理动作是捕捉,则调用了信号处理函数之后pause返回-1,errno设置为EINTR,所以pause只有出错的返回值。错误码EINTR表示“被信号中断”。

alarm函数可以参考这里:http://blog.csdn.net/simba888888/article/details/8944647

下面使用pause和alarm实现sleep(3)函数,称为mysleep:

#include<stdio.h>
#include<signal.h>
#include<unistd.h>
    
void sig_alrm(int signo)
{
    /* nothing to do */
}
    
    
unsigned int mysleep(unsigned int nsecs)
{
    struct sigaction newact, oldact;
    unsigned int unslept;
    
    newact.sa_handler = sig_alrm;
    sigemptyset(&newact.sa_mask);
    newact.sa_flags = 0;
    sigaction(SIGALRM, &newact, &oldact);
    
    alarm(nsecs);
    pause();
    
    unslept = alarm(0);
    sigaction(SIGALRM, &oldact, NULL);
    
    return unslept;
}
    
int main(void)
{
    while (1)
    {
        mysleep(2);
        printf("Two seconds passedn");
    }
    return 0;
}

1. main函数调用mysleep函数,后者调用sigaction注册了SIGALRM信号的处理函数sig_alrm。

2. 调用alarm(nsecs)设定闹钟。

3. 调用pause等待,内核切换到别的进程运行。

4. nsecs秒之后,闹钟超时,内核发SIGALRM给这个进程。

5. 从内核态返回这个进程的用户态之前处理未决信号,发现有SIGALRM信号,其处理函数是sig_alrm。

6. 切换到用户态执行sig_alrm函数,进入sig_alrm函数时SIGALRM信号被自动屏蔽,从sig_alrm函数返回时SIGALRM信号自动解除屏蔽。然后自动执行系统调用sigreturn再次进入内核,再返回用户态继续执行进程的主控制流程(main函数调用的mysleep函数)。

(编辑:佛山站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读