>>>signal函数之怪现象
来源: 互联网 发布时间:2015-03-17
本文导语: read程序可能产生阻塞现象,所以我采用signal函数来定时。 ... signal(SIGALRM,sigint_handler); alarm(5); nbytes = read(connfd,buf,1024); alarm(0); ... 其中sigint_handler是只有return 的...
read程序可能产生阻塞现象,所以我采用signal函数来定时。
...
signal(SIGALRM,sigint_handler);
alarm(5);
nbytes = read(connfd,buf,1024);
alarm(0);
...
其中sigint_handler是只有return 的函数。
现在的问题是:我经过测试,发现执行sigint_handler之后,程序回到read函数继续执行(因为这个时候客户端write数据的时候read函数能返回正常的结果)。
问题:我怎么才能实现read函数返回 EINTR 结果呢??????
珠江路上超强的IT厕所
----------------------------------------
昨日,去逛电脑城,突然觉得一阵腹痛,不好,要如厕。
急匆匆来到WC前,抬头只见门口上方挂一电子牌:上写
“WINDOWS XP HOME WC”
不禁赞叹:不愧是珠江路,果然是IT,高科技!
好急,快进去,怎么门推不开?抬头一看,电子板上显示:
“用户名不存在或密码错误,请找管理员”
给看门老头交了五毛钱,拿了个密码,急忙入内,冲向马桶
可是马桶盖怎么也打不开,我实在忍不住了,用力一拉,墙上弹出一块牌子:
“!系统提示:您没有这个马桶的访问权限”
**!好在我知道一个超级用户密码,这时起了作用,在控制面板中输入后,
马桶盖终于打开了…..长输了一口气,好舒服哦。
完事,伸手去拿手纸,手纸却又没法从盒子里抽出来,不会吧,难道?
一转头,果然,又弹出了一个牌子
“此纸盒已加密!”
我晕,正在急不可耐时,旁边蹲位有人伸过来一只手:
“你第一次用WINXP WC吧,没关系,我们手纸共享好了”
谢谢,谢谢, 边道谢,边提好裤子,
一冲马桶,又弹一牌子:
“病毒已清除!”
刚走两步,只听“砰”的一声,马桶盖大力的关上了,牌子上道:
“连接超时,请刷新!”
好险!!!
...
signal(SIGALRM,sigint_handler);
alarm(5);
nbytes = read(connfd,buf,1024);
alarm(0);
...
其中sigint_handler是只有return 的函数。
现在的问题是:我经过测试,发现执行sigint_handler之后,程序回到read函数继续执行(因为这个时候客户端write数据的时候read函数能返回正常的结果)。
问题:我怎么才能实现read函数返回 EINTR 结果呢??????
珠江路上超强的IT厕所
----------------------------------------
昨日,去逛电脑城,突然觉得一阵腹痛,不好,要如厕。
急匆匆来到WC前,抬头只见门口上方挂一电子牌:上写
“WINDOWS XP HOME WC”
不禁赞叹:不愧是珠江路,果然是IT,高科技!
好急,快进去,怎么门推不开?抬头一看,电子板上显示:
“用户名不存在或密码错误,请找管理员”
给看门老头交了五毛钱,拿了个密码,急忙入内,冲向马桶
可是马桶盖怎么也打不开,我实在忍不住了,用力一拉,墙上弹出一块牌子:
“!系统提示:您没有这个马桶的访问权限”
**!好在我知道一个超级用户密码,这时起了作用,在控制面板中输入后,
马桶盖终于打开了…..长输了一口气,好舒服哦。
完事,伸手去拿手纸,手纸却又没法从盒子里抽出来,不会吧,难道?
一转头,果然,又弹出了一个牌子
“此纸盒已加密!”
我晕,正在急不可耐时,旁边蹲位有人伸过来一只手:
“你第一次用WINXP WC吧,没关系,我们手纸共享好了”
谢谢,谢谢, 边道谢,边提好裤子,
一冲马桶,又弹一牌子:
“病毒已清除!”
刚走两步,只听“砰”的一声,马桶盖大力的关上了,牌子上道:
“连接超时,请刷新!”
好险!!!
|
使用setjmp/longjmp函数。
#include
#include
#include
static void sig_alrm(int)
static jmp_buf env_alrm;
int main(void)
{
if(signal( SIGALRM, sig_alrm) == SIG_ERR ) {
perror(argv[0]);exit(1);
}
if ( setjmp(env_alrm) != 0 ) {
printf("read time out" );
exit(1);
}
alarm(10);
nbytes = read(connfd,buf,1024);
alarm(0);
exit(0);
}
static void
sig_alrm(int signo)
{
longjmp(env_alrm,1);
}
#include
#include
#include
static void sig_alrm(int)
static jmp_buf env_alrm;
int main(void)
{
if(signal( SIGALRM, sig_alrm) == SIG_ERR ) {
perror(argv[0]);exit(1);
}
if ( setjmp(env_alrm) != 0 ) {
printf("read time out" );
exit(1);
}
alarm(10);
nbytes = read(connfd,buf,1024);
alarm(0);
exit(0);
}
static void
sig_alrm(int signo)
{
longjmp(env_alrm,1);
}
|
read()系统调用被信号中断就会返回errno=4, 即EINTR, 但是, os不同, 也不一定, 这是就看系统是否运行"被中断的系统调用是否继续运行"了, 即SA_RESTART标志了, 在sco和aix上默认是关SA_RESTART标志的, 在solaris上好像是开的.
如下程序:就返回errno为EINTR
#include
#include
#include
#include
#include
void sigalrm_hander( int signo )
{
printf( "in sigalrm_hander()n");
return;
}
extern int errno;
main()
{
int nbyte;
char buff[200];
signal( SIGALRM, sigalrm_hander);
alarm( 5 );
nbyte = read( 1, buff, sizeof(buff)-1);
alarm( 0);
printf( "main() end, nbyte = %d, errno = %d %sn", nbyte, errno, strerror(errno));
return 0;
}
此程序在aix上运行, 返回
in sigalrm_hander()
main() end, nbyte = -1, errno = 4 Interrupted system call
但如下程序
#include
#include
#include
#include
#include
void sigalrm_hander( int signo )
{
printf( "in sigalrm_hander()n");
return;
}
extern int errno;
void set_signal_handle( void )
{
struct sigaction act;
memset( &act, 0, sizeof(struct sigaction) );
act.sa_handler = sigalrm_hander;
sigemptyset( &act.sa_mask );
#ifdef SA_RESTART
act. sa_flags= SA_RESTART;
#endif
sigaddset( &act.sa_mask, SIGALRM );
sigaction( SIGALRM, &act, NULL );
return;
}
main()
{
int nbyte;
char buff[200];
set_signal_handle();
alarm( 5 );
nbyte = read( 1, buff, sizeof(buff)-1);
alarm( 0);
printf( "main() end, nbyte = %d, errno = %d %sn", nbyte, errno, strerror(errno));
return 0;
}
在aix下运行, 返回
in sigalrm_hander()// 信号程序执行后, 主程序没有退出
asdfsaf // 这时输入并回车
main() end, nbyte = 7, errno = 82 Restart the system call
如果把上面两个程序的信号处理的return改为exit(1), 则不论什么情况, 主程序都退出
!!!!!!!!!如果答对了你的问题, 一定要给分!!!!!!!!!!!!!!!
如下程序:就返回errno为EINTR
#include
#include
#include
#include
#include
void sigalrm_hander( int signo )
{
printf( "in sigalrm_hander()n");
return;
}
extern int errno;
main()
{
int nbyte;
char buff[200];
signal( SIGALRM, sigalrm_hander);
alarm( 5 );
nbyte = read( 1, buff, sizeof(buff)-1);
alarm( 0);
printf( "main() end, nbyte = %d, errno = %d %sn", nbyte, errno, strerror(errno));
return 0;
}
此程序在aix上运行, 返回
in sigalrm_hander()
main() end, nbyte = -1, errno = 4 Interrupted system call
但如下程序
#include
#include
#include
#include
#include
void sigalrm_hander( int signo )
{
printf( "in sigalrm_hander()n");
return;
}
extern int errno;
void set_signal_handle( void )
{
struct sigaction act;
memset( &act, 0, sizeof(struct sigaction) );
act.sa_handler = sigalrm_hander;
sigemptyset( &act.sa_mask );
#ifdef SA_RESTART
act. sa_flags= SA_RESTART;
#endif
sigaddset( &act.sa_mask, SIGALRM );
sigaction( SIGALRM, &act, NULL );
return;
}
main()
{
int nbyte;
char buff[200];
set_signal_handle();
alarm( 5 );
nbyte = read( 1, buff, sizeof(buff)-1);
alarm( 0);
printf( "main() end, nbyte = %d, errno = %d %sn", nbyte, errno, strerror(errno));
return 0;
}
在aix下运行, 返回
in sigalrm_hander()// 信号程序执行后, 主程序没有退出
asdfsaf // 这时输入并回车
main() end, nbyte = 7, errno = 82 Restart the system call
如果把上面两个程序的信号处理的return改为exit(1), 则不论什么情况, 主程序都退出
!!!!!!!!!如果答对了你的问题, 一定要给分!!!!!!!!!!!!!!!