gethostbyname()进程即使从不同线程中也能一致地解析? [英] gethostbyname() processes resolving consistently even from different threads?

查看:196
本文介绍了gethostbyname()进程即使从不同线程中也能一致地解析?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I conducted an experiment with DNS resolving by gethostbyname() from different threads. I turned off network link and ran program below. And output was like this


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秒的超时时间一一结束.

gethostbyname() started at the same time, but finished one by one with 40 sec timeout.

然后我使用getaddrinfo()进行了实验.而且看起来这个函数没有遇到这个问题

Then i experemented with getaddrinfo(). And it looks like this function doesn't suffer from this problem


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?

So, why I got this result and is this behavior specific for Linux only?

#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(),而freeaddrinfo()依次使用free()分配数据.因此,允许您从多个线程同时运行getaddrinfo(),并且各个实例并行运行.

The getaddrinfo() function doesn't share any global/static variables and is thus reentrant an therefore thread-safe. It returns result in memory allocated using malloc() and the user is responsible for using freeaddrinfo() which in turn uses free() to allocate the data. Therefore you are allowed to run getaddrinfo() simultaneously from multiple threads and the the individual instances run in parallel.

另一方面,gethostbyname()返回指向全局/静态数据的指针,因此

On the other hand, gethostbyname() returns a pointer to global/static data and thus is not reentrant. The user is not responsible for freeing the data. Therefore you are not allowed to run gethostbyname() simultaneously from multiple threads. According to your tests, the GNU C library apparently serializes the calls to avoid errors resulting from the parallel run.

您通常应该避免使用gethostbyname(),因为getaddrinfo()在某些程度上已经废弃了它,但是后者是

You should generally avoid using gethostbyname() as it's somewhat obsoleted by getaddrinfo() but the latter is not a perfect replacement, at least in glibc. I would recommend using getaddrinfo() and employ workarounds for its bugs where appropriate.

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

You could find out more by examining the source code.

这篇关于gethostbyname()进程即使从不同线程中也能一致地解析?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆