gethostbyname() processes resolving consistently even from different threads?

老子叫甜甜 提交于 2019-12-10 10:29:46

问题


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() started at the same time, but finished one by one with 40 sec timeout.

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

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

回答1:


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.

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.

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.



来源:https://stackoverflow.com/questions/25951925/gethostbyname-processes-resolving-consistently-even-from-different-threads

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!