linux系统编程之信号(六) 竞态条件与sigsuspend函数
一、利用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函数)。
(编辑:佛山站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |