>>>signal函数之怪现象

daehappy 2003-06-18 07:08:10
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吧,没关系,我们手纸共享好了”

谢谢,谢谢, 边道谢,边提好裤子,

一冲马桶,又弹一牌子:

“病毒已清除!”

刚走两步,只听“砰”的一声,马桶盖大力的关上了,牌子上道:

“连接超时,请刷新!”

好险!!!
...全文
34 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
super_lzy 2003-06-19
  • 打赏
  • 举报
回复
read()系统调用被信号中断就会返回errno=4, 即EINTR, 但是, os不同, 也不一定, 这是就看系统是否运行"被中断的系统调用是否继续运行"了, 即SA_RESTART标志了, 在sco和aix上默认是关SA_RESTART标志的, 在solaris上好像是开的.
如下程序:就返回errno为EINTR
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>

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 %s\n", nbyte, errno, strerror(errno));
return 0;
}
此程序在aix上运行, 返回
in sigalrm_hander()
main() end, nbyte = -1, errno = 4 Interrupted system call

但如下程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>

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 %s\n", nbyte, errno, strerror(errno));
return 0;
}
在aix下运行, 返回

in sigalrm_hander()// 信号程序执行后, 主程序没有退出
asdfsaf // 这时输入并回车
main() end, nbyte = 7, errno = 82 Restart the system call

如果把上面两个程序的信号处理的return改为exit(1), 则不论什么情况, 主程序都退出




!!!!!!!!!如果答对了你的问题, 一定要给分!!!!!!!!!!!!!!!

daehappy 2003-06-19
  • 打赏
  • 举报
回复
还是一样的结果
ari 2003-06-18
  • 打赏
  • 举报
回复
使用setjmp/longjmp函数。
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>

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);
}

23,114

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧