Нужно их все преобразовать в имена (я использую 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++' — ПК
Согластно требованиям POSIX (то есть на Юниксе) — gethostbyaddr является
потоко — небезопасной. То есть, ее надо закрывать мютексами.
Но, коль скоро речь идет о Win32 и Winsock — в документации gethostbyaddr
о потоковой безопасности нет ни слова. А это, следуя соглашениям Win32 API,
означает что она должна быть потоко-безопасной.
Лично я бы предпочел перебдеть чем недобдеть — то есть закрыл бы вызов
gethostbyaddr мютексом.
____________________
God obviously didn't debug, hasn't done any maintenance, and no documentation can be found. Truly amateur work.
Re[2]: gethostbyaddr и CreateThread
От:
Аноним
Дата:
08.05.03 14:05
Оценка:
Здравствуйте, TepMuHyc, Вы писали:
TMH>Согластно требованиям POSIX (то есть на Юниксе) — gethostbyaddr является TMH>потоко — небезопасной. То есть, ее надо закрывать мютексами.
TMH>Но, коль скоро речь идет о Win32 и Winsock — в документации gethostbyaddr TMH>о потоковой безопасности нет ни слова. А это, следуя соглашениям Win32 API, TMH>означает что она должна быть потоко-безопасной.
TMH>Лично я бы предпочел перебдеть чем недобдеть — то есть закрыл бы вызов TMH>gethostbyaddr мютексом.
А мог бы привести пример (как закрыть gethostbyaddr мютексом)? Я первый раз имею дело с потоками.
int main(int argc,char *argv[])
{
g_mxGethostbyaddr = [msdn]CreateMutex[/msdn](NULL,FALSE,NULL);
....
____________________
God obviously didn't debug, hasn't done any maintenance, and no documentation can be found. Truly amateur work.
Re: gethostbyaddr и CreateThread
От:
Аноним
Дата:
08.05.03 14:54
Оценка:
Здравствуйте, Аноним, пишет вам Аноним
А>Есть глобальная структура состоящая из двух векторов vector <string>. А>И в том и в том векторе находятся IP адреса.
Я так понял, что ты хочешь весь список обработать за раз?
То есть на каждую запись создать свой поток.
А в потоке собираешься использовать (как сказал товарищ ТерМиНус),
потоко-небезопасную функцию (если это так конечно).
Для обеспечения безопасности создавать мьютекс(или семафор, что быстрее)
Так вот, к чему я это: при этом раскладе ты НЕ ПОЛУЧИШЬ ВЫИГРАША в скорости.
А даже наверное проиграешь во времени (за счет всех этих мьютексов и потоков).
Из-за блокировки общего ресурса (в данном случае gethostbyaddr), все
будет выполнятся ПОСЛЕДОВАТЕЛЬНО, а НЕ ПАРАЛЛЕЛЬНО как ты наверное ожидаешь.
так что не выкаблучивайся, и делай последовательно.
PS: все сказанное имеет силу если gethostbyaddr действительно незащищенная
от параллельных вызовов.
[skipped] А>Кто разбирается в многопотоковом программировании — напишите пожалуйста как правильно А>надо. Код компилируется нормально. Только заполните вектора структуры своими адресами и А>подключите библиотеку ws2_32.lib.
Попробуй использовать _beginthreadex вместо CreateThread.
Re[2]: gethostbyaddr и CreateThread
От:
Аноним
Дата:
08.05.03 16:17
Оценка:
Попробовал с мутексом — все работает стабильно — но также медленно как и при последовательной обработке. А вот с семафором все летает. Работает почти мгновенно. Но не стабильно. Неужели никто не работал с потоками? Как мне исправить код с семафором чтобы
он работал стабильно?
Кстати. Попробовал beginthread — компилятор ругается:
error C2664: '_beginthreadex' : cannot convert parameter 3 from 'unsigned long (__stdcall *)(void *)' to 'unsigned int (__stdcall *)(void *)'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
Как это исправить?
Здравствуйте, Аноним, Вы писали:
А>error C2664: '_beginthreadex' : cannot convert parameter 3 from 'unsigned long (__stdcall *)(void *)' to 'unsigned int (__stdcall *)(void *)' А>This conversion requires a reinterpret_cast, a C-style cast or function-style cast А>Как это исправить?
Нутк сказано же — преобразуй тип. Даже написали в какой именно.
Здравствуйте, TepMuHyc, Вы писали:
TMH>Согластно требованиям POSIX (то есть на Юниксе) — gethostbyaddr является TMH>потоко — небезопасной. То есть, ее надо закрывать мютексами.
Это такое требование? Потоко небезопасность? И чем критические секции не угодили?
Здравствуйте, adontz, Вы писали:
TMH>>Согластно требованиям POSIX (то есть на Юниксе) — gethostbyaddr является TMH>>потоко — небезопасной. То есть, ее надо закрывать мютексами.
A>Это такое требование? Потоко небезопасность?
Читаем здесь: http://www.opengroup.org/onlinepubs/007904975/functions/xsh_chap02_09.html
A>И чем критические секции не угодили?
Тем что они только на винде и присутствуют...
____________________
God obviously didn't debug, hasn't done any maintenance, and no documentation can be found. Truly amateur work.
Re: gethostbyaddr и CreateThread
От:
Аноним
Дата:
09.10.03 05:34
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Нужно их все преобразовать в имена (я использую gethostbyaddr).
gethostbyaddr -- thrеadsafe, НО!!!!!!
The pointer which is returned points to a structure which is allocated by WinSock . The application must never attempt to modify this structure or to free any of its components. Furthermore, only one copy of this structure is allocated per thread, and so the application should copy any information which it needs before issuing any other WinSock API calls.