阻塞I/O的两种超时控制方法
时间:2006-03-13 来源:rwen2012
a. set a alarm, and get the EINTR
sample:
#define MAXTRY 3
void sig_alarm(int signo){return};
extern errno;
int count=0;
signal(SIGALRM, sig_alarm);
{
...
alarm(nsec);
tryagain:
//send the request
write(fd,outbuff, sizeof(outbuff);
//then read the reply
if ( read(fd, buff, sizeof(buff)) < 0)
{
if (errno == EINTR && ++count<MAXTRY)
goto tryagain;
return (-1);
}
alarm(0); //reset the timer
b.using the sigsetjump and siglongjump
sample:
void sig_alarm_jmp(int signo)
{
if (canjump == 0)
return;
siglongjmp(jmpbuf, 1);
}
{
...
signal(SIGALRM, sig_arlm_jmp);
if (sigsetjmp(jmpbuf, 1))
{
if (count >= MAXTRY)
exit(-1); //read error
printf("time out\n"); //time out, try again
nsec *= 2;
}
canjmp = 1;
//send the request
write(fd, outbuff, sizeof(outbuff));
count++;
alarm(nsec);
read(fd, buff, sizeof(buff));
canjmp = 0;
alarm(0);
...
}
注:这里设置了一个变量canjump,来控制是否执行非本地跳转。write
一个请求出去,然后程序读阻塞,直到读到应答或超时。现在假设在读
阻塞时超时,进程收到一个SIGALRM信号,于是它便执行信号处理函数。
由于这时canjump==1,所以执行siglongjmp(),远跳转到
sigsetjmp()处重复执行,到这里,进程检查其尝试的次数是否超过
MAXTRY,若是,则退出该进程,否则再次继续执行发送请求,然后再次
在读应答处阻塞。
显然,a方法的代码较为简单,但a方法用于系统调用被中断时不会自动重启的系统,而b方法则可以用于这种系统,即在系统自动重起的系统中可以用这个方法。
sample:
#define MAXTRY 3
void sig_alarm(int signo){return};
extern errno;
int count=0;
signal(SIGALRM, sig_alarm);
{
...
alarm(nsec);
tryagain:
//send the request
write(fd,outbuff, sizeof(outbuff);
//then read the reply
if ( read(fd, buff, sizeof(buff)) < 0)
{
if (errno == EINTR && ++count<MAXTRY)
goto tryagain;
return (-1);
}
alarm(0); //reset the timer
b.using the sigsetjump and siglongjump
sample:
void sig_alarm_jmp(int signo)
{
if (canjump == 0)
return;
siglongjmp(jmpbuf, 1);
}
{
...
signal(SIGALRM, sig_arlm_jmp);
if (sigsetjmp(jmpbuf, 1))
{
if (count >= MAXTRY)
exit(-1); //read error
printf("time out\n"); //time out, try again
nsec *= 2;
}
canjmp = 1;
//send the request
write(fd, outbuff, sizeof(outbuff));
count++;
alarm(nsec);
read(fd, buff, sizeof(buff));
canjmp = 0;
alarm(0);
...
}
注:这里设置了一个变量canjump,来控制是否执行非本地跳转。write
一个请求出去,然后程序读阻塞,直到读到应答或超时。现在假设在读
阻塞时超时,进程收到一个SIGALRM信号,于是它便执行信号处理函数。
由于这时canjump==1,所以执行siglongjmp(),远跳转到
sigsetjmp()处重复执行,到这里,进程检查其尝试的次数是否超过
MAXTRY,若是,则退出该进程,否则再次继续执行发送请求,然后再次
在读应答处阻塞。
显然,a方法的代码较为简单,但a方法用于系统调用被中断时不会自动重启的系统,而b方法则可以用于这种系统,即在系统自动重起的系统中可以用这个方法。
相关阅读 更多 +
排行榜 更多 +