在Linux环境下gethostbyname函数是用来向DNS查询一个域名的IP地址。 由于DNS的查询方式是递归查询,在网络不通的情况下会导致gethostbyname函数在查询一个域名时出现严重超时问题。而该函数又不能像connect和read等函数那样通过setsockopt或者select函数那样设置超时时间,因此常常成为程序开发的瓶颈。
在多线程环境下,gethostbyname会出现一个非常严重的问题,就是如果有一个线程的gethostbyname发生阻塞,其它线程都会在gethostbyname处发生阻塞,直到该线程的gethostbyname函数返回为止。针对这样的问题我们应该怎么处理呢?
下面介绍两种方法:
1、 使用alarm设定信号,如果超时就用sigsetjmp和siglongjmp跳过gethostbyname函数。
2、 独立开启一个线程来调用gethostbyname函数,该线程除了调用此函数外,不做任何事情。
二、方法介绍
1、alarm设定信号方法
(1)、sigsetjmp和siglongjmp概述
sigsetjmp: 参数为非0的时候,会保存进程的当前信号屏蔽字
siglongjmp: 恢复保存的信号屏蔽字
(2)、使用方法
#include <setjmp.h>
#include <time.h>
static sigjmp_buf jmpbuf
static void alarm_func()
{
siglongjmp(jmpbuf, 1)
}
static struct hostent *gngethostbyname(char *HostName, int timeout)
{
struct hostent *lpHostEnt
signal(SIGALRM, alarm_func)
if(sigsetjmp(jmpbuf, 1) != 0)
{
alarm(0)/* 取消闹钟 */
signal(SIGALRM, SIG_IGN)
return NULL
}
alarm(timeout)/* 设置超时时间 */
lpHostEnt = gethostbyname(HostName)
signal(SIGALRM, SIG_IGN)
return lpHostEnt
}
TCP超时总共分为3类,即连接超时,读超时,写超时,这三种超时设置办法如下:1、连接超时:超时时间系统是有最大限制的,如果想要自己设置超时时间,可以采用alarm函数或者使用select函数,监听套接字是否有读或写性质的变化;
2、读写超时设置要用到函数setsockopt(),这个比较简单,直接在客户端设置一下就可以了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)