繁体   English   中英

gethostbyname()进程甚至从不同的线程一致地解决?

[英]gethostbyname() processes resolving consistently even from different threads?

我通过gethostbyname()从不同的线程进行了DNS解析实验。 我关闭了网络链接并运行下面的程序。 输出是这样的

gethostbyname started at 1411234734
gethostbyname started at 1411234734
gethostbyname started at 1411234734
gethostbyname finished at 1411234774
gethostbyname finished at 1411234814
gethostbyname finished at 1411234854

gethostbyname()同时启动,但是在40秒超时的情况下逐个完成。

然后我用getaddrinfo()进行了实验。 看起来这个功能不会遇到这个问题

getaddrinfo started at 1411235759
getaddrinfo started at 1411235759
getaddrinfo started at 1411235759
getaddrinfo finished at 1411235799
getaddrinfo finished at 1411235799
getaddrinfo finished at 1411235799

那么,为什么我得到了这个结果,这个行为只针对Linux?

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <time.h>
#include <pthread.h>

void *resolve_ghbn(void *host) {
    printf("gethostbyname started at %d\n", time(NULL));
    struct hostent *rslv = gethostbyname((char*)host);
    printf("gethostbyname finished at %d\n", time(NULL));

    return NULL;
}

void *resolve_gai(void *host) {
    struct addrinfo *result;
    printf("getaddrinfo started at %d\n", time(NULL));
    int res = getaddrinfo(host, NULL, NULL, &result);
    printf("getaddrinfo finished at %d\n", time(NULL));
    if (res == 0)
        freeaddrinfo(result);

    return NULL;
}

int main() {
    char *domains[] = {"google.com", "google.cy", "google.us"};
    pthread_t threads[3];
    int i;

    for (i=0; i<3; i++) {
        pthread_create(&threads[i], NULL, resolve_ghbn, domains[i]);
    }

    void *retval;

    for (i=0; i<3; i++) {
        pthread_join(threads[i], &retval);
    }

    return 0;
}

getaddrinfo()函数不共享任何全局/静态变量,因此可以重入,因此是线程安全的。 它返回使用malloc()分配的内存中的结果,用户负责使用freeaddrinfo() ,后者又使用free()来分配数据。 因此,您可以同时从多个线程运行getaddrinfo() ,并且各个实例并行运行。

另一方面, gethostbyname()返回指向全局/静态数据的指针,因此不可重入 用户不负责释放数据。 因此,您不能同时从多个线程运行gethostbyname() 根据您的测试,GNU C库显然会对调用进行序列化,以避免因并行运行而导致的错误。

你通常应该避免使用gethostbyname()因为它有点被getaddrinfo()淘汰,但后者不是一个完美的替代品 ,至少在glibc中。 我建议使用getaddrinfo()并在适当的地方使用变通方法。

您可以通过检查源代码了解更多信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM