views:

96

answers:

2

Hello,

I am working in C++ with VS2008 and Win7.

While examining a program I was following the threads created, and it seems that gethostbyname() creates a thread for itself. Could you explain why?

On msdn is says: "The memory for the hostent structure returned by the gethostbyname function is allocated internally by the Winsock DLL from thread local storage. "

Does this memory fool visual studio into thinking it is a thread?

EDIT: It seems that from this link, and also from my observations that this also happens with the Connect function. I guess this is normal behavior.

The code below is from msdn [gethostbyname page] and it exhibits the same behavior.

   int main(int argc, char **argv)

{

    //-----------------------------------------
// Declare and initialize variables
WSADATA wsaData;
int iResult;

DWORD dwError;
int i = 0;

struct hostent *remoteHost;
char *host_name;
struct in_addr addr;

char **pAlias;

// Validate the parameters
if (argc != 2) {
    printf("usage: %s hostname\n", argv[0]);
    printf("  to return the IP addresses for the host\n");
    printf("       %s www.contoso.com\n", argv[0]);
    printf(" or\n");
    printf("       %s IPv4string\n", argv[0]);
    printf("  to return an IPv4 binary address for an IPv4string\n");
    printf("       %s 127.0.0.1\n", argv[0]);
    return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
    printf("WSAStartup failed: %d\n", iResult);
    return 1;
}

host_name = argv[1];

printf("Calling gethostbyname with %s\n", host_name);
remoteHost = gethostbyname(host_name);

if (remoteHost == NULL) {
    dwError = WSAGetLastError();
    if (dwError != 0) {
        if (dwError == WSAHOST_NOT_FOUND) {
            printf("Host not found\n");
            return 1;
        } else if (dwError == WSANO_DATA) {
            printf("No data record found\n");
            return 1;
        } else {
            printf("Function failed with error: %ld\n", dwError);
            return 1;
        }
    }
} else {
    printf("Function returned:\n");
    printf("\tOfficial name: %s\n", remoteHost->h_name);
    for (pAlias = remoteHost->h_aliases; *pAlias != 0; pAlias++) {
        printf("\tAlternate name #%d: %s\n", ++i, *pAlias);
    }
    printf("\tAddress type: ");
    switch (remoteHost->h_addrtype) {
    case AF_INET:
        printf("AF_INET\n");
        break;
    case AF_NETBIOS:
        printf("AF_NETBIOS\n");
        break;
    default:
        printf(" %d\n", remoteHost->h_addrtype);
        break;
    }
    printf("\tAddress length: %d\n", remoteHost->h_length);

    i = 0;
    if (remoteHost->h_addrtype == AF_INET)
    {
        while (remoteHost->h_addr_list[i] != 0) {
            addr.s_addr = *(u_long *) remoteHost->h_addr_list[i++];
            printf("\tIP Address #%d: %s\n", i, inet_ntoa(addr));
        }
    }
    else if (remoteHost->h_addrtype == AF_NETBIOS)
    {   
        printf("NETBIOS address was returned\n");
    }   
}

return 0;

}

+1  A: 

No, the Thread-local storage is unrelated to the startup of a new thread.

The thread may be needed due to thread-affinity issues with sub-operations of the GetHostByName API, such as the need to use asynchronous callbacks without affecting the calling thread's re-entrancy.

Or it may be a lazy initialization feature of WinSock where a daemon thread needed for a subset of WinSock operations is needed, and this was the first API to require the daemon.

David Gladfelter
+1  A: 

AFAIK, gethostbyname blocks.

WinSock often creates some helper threads though.

Pavel Radzivilovsky