gethostbyaddr и CreateThread
От: Аноним  
Дата: 08.05.03 13:31
Оценка:
Есть глобальная структура состоящая из двух векторов vector <string>.
И в том и в том векторе находятся IP адреса.


typedef struct addr_table {
    vector <string> LocalAddress;
    vector <string> RemoteAddress;
} addr_table;

addr_table addrtable;


Нужно их все преобразовать в имена (я использую gethostbyaddr).
Если делать это последовательно то получается очень медленно.

Поэтому я решить преобразовывать их в имена используя CreateThread
и CreateSemaphore.

Но т.к. я раньше никогда не писал многопотоковые приложения то все
работает нестабильно. Некоторые адреса преобразовываются.
Иногда. А некоторые нет. А бывает что и все нормально.

Вот функция которая вызывается в многопотоковом режиме:


DWORD WINAPI resolve(LPVOID lp)
{
    int i=(int)lp;

    hostent *h = NULL;
    unsigned int addr = inet_addr(addrtable.LocalAddress[i].c_str());
    h = gethostbyaddr(reinterpret_cast<char *>(&addr), 4, AF_INET);
    if (h != NULL)
    {
        addrtable.LocalAddress[i] = h->h_name;
    }

    Теперь тоже самое для addrtable.RemoteAddress[i].
    Потом:

    Sleep(500);
    ReleaseSemaphore(hSemaphore,1, NULL);

    return 0;
}


А вот код который вызывает эту функцию:


#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <string>

using namespace std;

long MaxThread=100;
HANDLE hSemaphore;
long PreviousCount=0;

DWORD WINAPI resolve(LPVOID lp);

int main(int argc,char *argv[])
{
    HANDLE hThread=NULL;
    DWORD dwThreadID;

    BOOL ret;
    WSADATA wsa;
    int  i;

    ret = WSAStartup( 0x0101, &wsa );

    hSemaphore=CreateSemaphore(NULL,MaxThread,MaxThread,NULL);
 
    for(i=0;i<addrtable.LocalAddress.size();i++)
    {
        hThread=CreateThread(NULL, 0, resolve, (LPVOID)i , 0, &dwThreadID);
        Sleep(10);
        CloseHandle(hThread);
        WaitForSingleObject(hSemaphore, INFINITE);
    }

    while(1)
    {
        WaitForSingleObject(hSemaphore, INFINITE);
        if(!ReleaseSemaphore(hSemaphore, 1, &PreviousCount))
        {
            Sleep(5000);
            break;
        }

        if(PreviousCount=(MaxThread-1))
        {
            break;
        }
        Sleep(500);
    }

    CloseHandle(hSemaphore);    

    А теперь выводим то что получилось:

    for(i=0;i<addrtable.LocalAddress.size();i++)
    {
        cout << addrtable.LocalAddress[i] << endl;
        cout << addrtable.RemoteAddress[i] << endl;
    }

    WSACleanup();

    return 0;
}


Кто разбирается в многопотоковом программировании — напишите пожалуйста как правильно
надо. Код компилируется нормально. Только заполните вектора структуры своими адресами и
подключите библиотеку ws2_32.lib.

08.05.03 18:41: Перенесено модератором из 'C/C++' — ПК
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.