Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> подвисает wininet 
:(
    Опции темы
Satell
Дата 24.8.2007, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 79
Регистрация: 28.6.2007

Репутация: нет
Всего: нет



вот есть такой код получающий страницы по winnet,
зачастую после вывода строки HttpOpenRequest Successfull перед функцией HttpSendRequest программа подвисает на несколько минут, либо очень надолго, можно ли сделать какой-нибудь таймаут для этих ф-й?

Код

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



PM MAIL   Вверх
Satell
Дата 24.8.2007, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 79
Регистрация: 28.6.2007

Репутация: нет
Всего: нет



как запихать эту функцию в отдельный поток?
PM MAIL   Вверх
Satell
Дата 24.8.2007, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 79
Регистрация: 28.6.2007

Репутация: нет
Всего: нет



у меня там ещё таймер есть, а getpage вызвается из обработчика события таймера в цикле, что тогда конкретно в потоке запускать? может есть где простой иходничек работы с потоками? а что происходит в том случае, если код в потоках ещё не отпработал, а наступает следующее событие таймера, например код в каком-то потоке не может получить страницу и подвис, этот код уничтожется или эти недоработавшие потоки будут висеть где-то в памяти?
а сам по себе таймер не создает отдельные потоки случайно?

int CALLBACK TimerProc(void)
{

for (int j=0; j<numsites; j++)
{

//поток должен создаваться гдето тут?!!!
pagedata=getpage(...);
//действия с pagedata

//ещё два раза
getpage(...);
getpage(...);
//поток должен заканчиваться гдето тут!!!

}

} 

PM MAIL   Вверх
ptr
Дата 27.8.2007, 06:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



Satell, используй асинхронный режим.


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
Satell
Дата 30.8.2007, 22:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 79
Регистрация: 28.6.2007

Репутация: нет
Всего: нет



делаю потоки таким образом с таймаутом 5 сек, виснуть перестало, но иногда возникает такое, что пропадает связь на модеме и все идет в таймаут "Can not connect to server" ровно раз в 5 сек, пока не завершишь программу, перегрузка какая-то чтоли, по идее все потоки должны завершаться через 5 сек, всё ли правильно в программе? а как сделать чтобы потоки работали параллельно несколько или они и так работают, но почему тогда puts(pThreadParm->url); выводит ровно раз в 5 сек...

Код

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



Это сообщение отредактировал(а) Satell - 30.8.2007, 22:14
PM MAIL   Вверх
ptr
Дата 31.8.2007, 05:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



Satell, скажи а зачем тут вообще нужны потоки? Вначале цикла ты создаешь поток, потом ждешь пока он завершится. Смысл тогда создавать поток?


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
Satell
Дата 31.8.2007, 06:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 79
Регистрация: 28.6.2007

Репутация: нет
Всего: нет



функции wininet не позволяют делать тайм аут, когда много страниц закачиваются, на одной виснет всё приложение, я реализую так таймаут для wininet функций, которые в WorkerFunction
PM MAIL   Вверх
ptr
Дата 31.8.2007, 07:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



Цитата(Satell @  31.8.2007,  09:33 Найти цитируемый пост)
гда много страниц закачиваются, на одной виснет всё приложение

Я это понимаю, но в твоём коде работает только один поток. В цикле ты его создал, потом ждесь пока он завершится. Зачем в цикле ожидание (WaitForSingleObject)?


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
Satell
Дата 31.8.2007, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 79
Регистрация: 28.6.2007

Репутация: нет
Всего: нет



в WorkerFunction вызывается getpage (см. первое сообщение), которая часто подвешивается, WaitForSingleObject ждёт 5 сек и потом по идее должна завершать поток, я думал это делает CloseHandle (hThread), но она этого не делает!!! копиться много потоков, пока не сожрут все ресурсы системы, как грамотно завершить поток?

Код

if ( WaitForSingleObject ( hThread, dwTimeout ) == WAIT_TIMEOUT )
{
           cout << "Can not connect to server";
           ExitThread(dwThreadID);       //при её использование тут программа просто виснет
           TerminateThread(hThread,0); // говорят некорректно освобождает ресурсы, в общем все ресурсы системы все равно сжираются, 
хотя потоков кажется меньше создаётся
                                              
}


Это сообщение отредактировал(а) Satell - 31.8.2007, 10:15
PM MAIL   Вверх
ptr
Дата 31.8.2007, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



Из вне грамотного способа завершить поток я не знаю. Обычно ставят флажок, который поток проверяет и если нужно корректно завершается. Но в твоем случае это не поможет (хотя можно попробовать вызвать InternetCloseHandle в главном потоке и тогда дочерний поток с блокировки должен слететь). 

Это сообщение отредактировал(а) ptr - 31.8.2007, 11:02


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
Satell
Дата 31.8.2007, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 79
Регистрация: 28.6.2007

Репутация: нет
Всего: нет



HINTERNET hInternet;
HINTERNET hConnect;
HINTERNET hRequest;
объявляю глобально

потом
if ( WaitForSingleObject ( hThread, dwTimeout ) == WAIT_TIMEOUT )
{
           cout << "Can not connect to server";
           InternetCloseHandle(hInternet);
           InternetCloseHandle(hConnect);
           InternetCloseHandle(hInternet);     
           WaitForSingleObject ( hThread, INFINITE );     
}
так вот фиг, потоки все равно не завершаются при закрытии дескрипторов ф-й winapi(
виснет похоже HttpSendRequest и как повиснет так вместе с потоком и висит и ничего с ней не поделаешь, а если не ждать WaitForSingleObject ( hThread, INFINITE );  тогда число потоков постоянно растет... почему никто не придумал таймауты для ф-й winapi?

Это сообщение отредактировал(а) Satell - 31.8.2007, 17:08
PM MAIL   Вверх
ptr
Дата 31.8.2007, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



Может быть hConnect стоит закрывать?

Посмотри ещё InternetSetOption.

Это сообщение отредактировал(а) ptr - 31.8.2007, 15:28


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
Satell
Дата 31.8.2007, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 79
Регистрация: 28.6.2007

Репутация: нет
Всего: нет



да всё закрываю что можно (ошибся на форуме) все равно поток не завершается, ждёт какой-то свой внутренний долгий тайм аут минут пять, что за хрень
PM MAIL   Вверх
Satell
Дата 31.8.2007, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 79
Регистрация: 28.6.2007

Репутация: нет
Всего: нет



программа должна быстро коннектица к большому числу url
Как избавиться от зависания InternetOpenUrl или HttpSendRequest? зависает похоже на 5 мин, при недоступности сервера, таймаут этот гдето в настройках броузера, поменять его нельзя, закрытие описателей winapi ф-й в таймауте выполнения потока не помогает, если убивать потоки TerminateThread, то потом интернет ломается, нет связи, видимо не освобождаются какие-то ресурсы так, если забивать на зависшие потоки, то потом их становится очень много и опять же интернет ломается
PM MAIL   Вверх
ptr
Дата 2.9.2007, 06:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



Вообще говоря поток после InternetCloseHandle должен слетать с блокировки. Выложи весь проект.

Это сообщение отредактировал(а) ptr - 2.9.2007, 07:00


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0532 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.