程序的初步想法是想试一试阻塞信号,用信号 SIGALRM 来实验
我先是 signal(SIGALRM, alrmhandler);
然后设置一个定时器,每隔一段时间发送一个 SIGALRM 给程序,
接着在函数 alrmhandler 里面将SIGALRM阻塞,但是却出现了 EINTR 的错误,
请问下是怎么回事啊!
具体程序在下面
#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
int cnt = 0;
void alrmblock(){
sigset_t sigs;
sigemptyset(&sigs);
sigaddset(&sigs, SIGALRM);
errno = 4;
sigprocmask(SIG_BLOCK, &sigs, NULL);
printf("%s\n",strerror(errno));
}
void alrmhandler(int signum){
alrmblock();
cnt ++;
printf("%d\n",cnt);
}
int main(){
signal(SIGALRM, alrmhandler);
struct itimerval it;
it.it_value.tv_sec = 1;
it.it_interval.tv_sec = 1;
it.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &it , NULL);
while(1) pause();
return 0;
}
求大牛帮忙看一下为什么我这个程序出现了 Interrupted system call 的错误啊
-
- 帖子: 10
- 注册时间: 2014-03-01 21:51
- 系统: ubuntu 13.10
- astolia
- 论坛版主
- 帖子: 6703
- 注册时间: 2008-09-18 13:11
Re: 求大牛帮忙看一下为什么我这个程序出现了 Interrupted system call 的错误啊
你这里不是写了么
errno = 4;
.......
printf("%s\n",strerror(errno));
当然必然会输出Interrupted system call
如果把errno = 4删掉,会先输出一个Success,再是一连串的Interrupted system call,这是因为pause()就是这么干的
以下摘自man 2 pause
RETURN VALUE
pause() returns only when a signal was caught and the signal-catching
function returned. In this case pause() returns -1, and errno is set
to EINTR.
errno = 4;
.......
printf("%s\n",strerror(errno));
当然必然会输出Interrupted system call
如果把errno = 4删掉,会先输出一个Success,再是一连串的Interrupted system call,这是因为pause()就是这么干的
以下摘自man 2 pause
RETURN VALUE
pause() returns only when a signal was caught and the signal-catching
function returned. In this case pause() returns -1, and errno is set
to EINTR.
-
- 帖子: 10
- 注册时间: 2014-03-01 21:51
- 系统: ubuntu 13.10
Re: 求大牛帮忙看一下为什么我这个程序出现了 Interrupted system call 的错误啊
astolia 写了:你这里不是写了么
errno = 4;
.......
printf("%s\n",strerror(errno));
当然必然会输出Interrupted system call
如果把errno = 4删掉,会先输出一个Success,再是一连串的Interrupted system call,这是因为pause()就是这么干的
以下摘自man 2 pause
RETURN VALUE
pause() returns only when a signal was caught and the signal-catching
function returned. In this case pause() returns -1, and errno is set
to EINTR.
那个erron = 4;是我调试的时候忘记删除了。。。
我这里主要是有这么一个问题
就是第一次接受alrm信号过后,进入alrmhandler,然后在alrmblock中已经把alrm信号屏蔽了才对啊
既然屏蔽了 那么为什么第二次信号来的时候 , 还能进入alrmhandler函数内呢?
- astolia
- 论坛版主
- 帖子: 6703
- 注册时间: 2008-09-18 13:11
Re: 求大牛帮忙看一下为什么我这个程序出现了 Interrupted system call 的错误啊
信号阻塞机制和你理解的有点不一样。在handler里设置的sigprocmask只对此次处理有效,不会影响到正常流程和下次handler的处理。而且,handler默认会阻塞当前收到的信号,所以说你在handler中再次设置阻塞是没有用的
代码: 全选
#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
int cnt = 0;
void alrmblock(){
sigset_t sigs;
sigemptyset(&sigs);
sigaddset(&sigs, SIGALRM);
sigaddset(&sigs, SIGTERM);
sigprocmask(SIG_BLOCK, &sigs, NULL);
printf("%s\n",strerror(errno));
}
void alrmhandler(int signum){
sigset_t sigs;
sigprocmask(0, NULL, &sigs);
printf("old SIGALRM: %d\n", sigismember(&sigs, SIGALRM));
printf("old SIGTERM: %d\n", sigismember(&sigs, SIGTERM));
alrmblock();
sigprocmask(0, NULL, &sigs);
printf("new SIGALRM: %d\n", sigismember(&sigs, SIGALRM));
printf("new SIGTERM: %d\n", sigismember(&sigs, SIGTERM));
cnt ++;
printf("%d\n",cnt);
}
int main(){
signal(SIGALRM, alrmhandler);
sigset_t sigs;
sigprocmask(0, NULL, &sigs);
printf("main SIGALRM: %d\n", sigismember(&sigs, SIGALRM));
printf("main SIGTERM: %d\n", sigismember(&sigs, SIGTERM));
raise(SIGALRM);
sigprocmask(0, NULL, &sigs);
printf("main SIGALRM: %d\n", sigismember(&sigs, SIGALRM));
printf("main SIGTERM: %d\n", sigismember(&sigs, SIGTERM));
raise(SIGALRM);
return 0;
}
-
- 帖子: 10
- 注册时间: 2014-03-01 21:51
- 系统: ubuntu 13.10
Re: 求大牛帮忙看一下为什么我这个程序出现了 Interrupted system call 的错误啊
知道怎么回事了 非常感谢啊!!astolia 写了:信号阻塞机制和你理解的有点不一样。在handler里设置的sigprocmask只对此次处理有效,不会影响到正常流程和下次handler的处理。而且,handler默认会阻塞当前收到的信号,所以说你在handler中再次设置阻塞是没有用的
代码: 全选
#include <stdio.h> #include <sys/time.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <string.h> #include <errno.h> #include <pthread.h> int cnt = 0; void alrmblock(){ sigset_t sigs; sigemptyset(&sigs); sigaddset(&sigs, SIGALRM); sigaddset(&sigs, SIGTERM); sigprocmask(SIG_BLOCK, &sigs, NULL); printf("%s\n",strerror(errno)); } void alrmhandler(int signum){ sigset_t sigs; sigprocmask(0, NULL, &sigs); printf("old SIGALRM: %d\n", sigismember(&sigs, SIGALRM)); printf("old SIGTERM: %d\n", sigismember(&sigs, SIGTERM)); alrmblock(); sigprocmask(0, NULL, &sigs); printf("new SIGALRM: %d\n", sigismember(&sigs, SIGALRM)); printf("new SIGTERM: %d\n", sigismember(&sigs, SIGTERM)); cnt ++; printf("%d\n",cnt); } int main(){ signal(SIGALRM, alrmhandler); sigset_t sigs; sigprocmask(0, NULL, &sigs); printf("main SIGALRM: %d\n", sigismember(&sigs, SIGALRM)); printf("main SIGTERM: %d\n", sigismember(&sigs, SIGTERM)); raise(SIGALRM); sigprocmask(0, NULL, &sigs); printf("main SIGALRM: %d\n", sigismember(&sigs, SIGALRM)); printf("main SIGTERM: %d\n", sigismember(&sigs, SIGTERM)); raise(SIGALRM); return 0; }
不过觉得pause的工作方式有点奇特。。