вот есть такой код получающий страницы по winnet, зачастую после вывода строки HttpOpenRequest Successfull перед функцией HttpSendRequest программа подвисает на несколько минут, либо очень надолго, можно ли сделать какой-нибудь таймаут для этих ф-й или как можно получать страницу с таймаутом? Code: char* getpage(char* userag,char* proxy, char* url, char* document, char* referer) { char szData[1500]; DWORD dwBytesRead; HINTERNET hInternet = ::InternetOpen(userag, INTERNET_OPEN_TYPE_PROXY, proxy,NULL,0); if (hInternet != NULL) { puts("internetOpen successfull"); HINTERNET hConnect =::InternetConnect(hInternet, url, INTERNET_DEFAULT_HTTP_PORT, NULL,NULL, INTERNET_SERVICE_HTTP,0,1u); if (hConnect != NULL) { puts("internetConnect successfull"); HINTERNET hRequest =::HttpOpenRequest(hConnect, TEXT("GET"), document, NULL, referer, 0, INTERNET_FLAG_KEEP_CONNECTION, 1); if (hRequest != NULL) { puts("HttpOpenRequest successfull"); //вот тут подвисает иногда!!! BOOL bSend = ::HttpSendRequest(hRequest, NULL,0, NULL,0); if (bSend) { puts("httpSendRequest successfull"); BOOL bRead = ::InternetReadFile(hRequest, szData,sizeof(szData)-1, &dwBytesRead); if (bRead == FALSE || dwBytesRead == 0) { puts("error readFile"); return 0; } szData[dwBytesRead] = 0; return szData; } ::InternetCloseHandle(hRequest); } ::InternetCloseHandle(hConnect); } / ::InternetCloseHandle(hInternet); } return 0; }
1) Делай структуру, содержащую из: char* userag, char* proxy, char* url, char* document, char* referer 2) Заполни эту структуру 3) Создавай поток и передавай указатель на эту структуру (см. CreateThread)
у меня там ещё таймер есть, а getpage вызвается из обработчика события таймера в цикле, что тогда конкретно в потоке запускать? может есть где простой иходничек работы с потоками? а что происходит в том случае, если код в потоках ещё не отпработал, а наступает следующее событие таймера, например код в каком-то потоке не может получить страницу и подвис, этот код уничтожется или эти недоработавшие потоки будут висеть где-то в памяти? а сам по себе таймер не создает отдельные потоки случайно? int CALLBACK TimerProc(void) { for (int j=0; j<numsites; j++) { //поток должен создаваться гдето тут?!!! pagedata=getpage(...); //действия с pagedata //ещё два раза getpage(...); getpage(...); //поток должен заканчиваться гдето тут!!! } }
Можешь, например, создавать отдельный поток для каждой страницы. Таймер отдельно работает, потоки тоже отдельно. Следовательно недоработавшие потоки будут дорабатывать.
делаю потоки таким образом с таймаутом 5 сек, виснуть перестало, но иногда возникает такое, что пропадает связь на модеме (нельзя открыть ничего в броузере) и все идет в таймаут "Can not connect to server" ровно раз в 5 сек, пока не завершишь программу, перегрузка какая-то чтоли, по идее все потоки должны завершаться через 5 сек, всё ли правильно в программе? а как сделать чтобы потоки работали параллельно несколько или они и так работают, но почему тогда puts(pThreadParm->url); выводит ровно раз в 5 сек... Code: DWORD WINAPI WorkerFunction( LPVOID ); typedef struct { char* url; ...структура данных для рабочей функции } PARM; int num=0; DWORD WINAPI WorkerFunction(IN LPVOID vThreadParm) //vThreadParm - points to PARM passed to thread { PARM* pThreadParm; // Initialize local pointer to void pointer passed to thread pThreadParm = (PARM*)vThreadParm; ...тут обрабатывающий код puts(pThreadParm->url); return 0; } int main(int argc, char* argv[]) { DWORD dwTimeout; PARM threadParm; HANDLE hThread; DWORD dwThreadID; for (int j=0; j<num; j++) { hThread = CreateThread( NULL, // Pointer to thread security attributes 0, // Initial thread stack size, in bytes WorkerFunction, // Pointer to thread function &threadParm, // The argument for the new thread 0, // Creation flags &dwThreadID // Pointer to returned thread identifier ); dwTimeout = 5000; // in milliseconds if ( WaitForSingleObject ( hThread, dwTimeout ) == WAIT_TIMEOUT ) { cout << "Can not connect to server"; } CloseHandle (hThread); } }
в WorkerFunction вызывается getpage (см. первое сообщение), которая часто подвешивается, WaitForSingleObject ждёт 5 сек и потом по идее должна завершать поток, я думал это делает CloseHandle (hThread), но она этого не делает!!! копиться много потоков, пока не сожрут все ресурсы системы, как грамотно завершить поток? Code: if ( WaitForSingleObject ( hThread, dwTimeout ) == WAIT_TIMEOUT ) { cout << "Can not connect to server"; ExitThread(dwThreadID); //при её использование тут программа просто виснет TerminateThread(hThread,0); // говорят некорректно освобождает ресурсы, в общем все ресурсы системы все равно сжираются, хотя потоков кажется меньше создаётся }
HINTERNET hInternet; HINTERNET hConnect; HINTERNET hRequest; объявляю глобально потом Code: if ( WaitForSingleObject ( hThread, dwTimeout ) == WAIT_TIMEOUT ) { cout << "Can not connect to server"; InternetCloseHandle(hInternet); InternetCloseHandle(hConnect); InternetCloseHandle(hRequest); WaitForSingleObject ( hThread, INFINITE ); } так вот фиг, потоки все равно не завершаются при закрытии дескрипторов ф-й winapi( виснет похоже HttpSendRequest и как повиснет так вместе с потоком и висит и ничего с ней не поделаешь, а если не ждать WaitForSingleObject ( hThread, INFINITE ); тогда число потоков постоянно растет... почему никто не придумал таймауты для ф-й winapi?
Люди, ну вы хотябы прежде чем писать многопоточные приложения, прочитайте про эту самую многопоточность. http://uinc.ru/articles/38/ Надеюсь хоть что-то прояснишь для себя.
ну да я жду тут пока поток завершиться, а он не завершается, виснет ф-я HttpSendrequest и висит вместе с потоком, так их накапливается очень много, если не ждать
программа должна быстро коннектица к большому числу url Как избавиться от зависания InternetOpenUrl или HttpSendRequest? зависает похоже на 5 мин, при недоступности сервера, таймаут этот гдето в настройках броузера, поменять его нельзя, закрытие описателей winapi ф-й в таймауте выполнения потока не помогает, если убивать потоки TerminateThread, то потом интернет ломается, нет связи, видимо не освобождаются какие-то ресурсы так, если забивать на зависшие потоки, то потом их становится очень много и опять же интернет ломается