Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.191.239.123] |
|
Сообщ.
#1
,
|
|
|
Прошу опять консультацию для работы с потоками. Создаю главный поток для выбора ссылок и помещения их в список, запускаю дочерние потоки для обработки этих ссылок. Через несколько минут, при выполнении задачи программа подвисает (был и случай успешного завершения). Не знаю, в чем проблемма.
P.S. в коде понаставлял блокировку списка и критические секции, но результат не изменился. // главный поток void __fastcall THThread::Execute() { String url, html; TStringList *pmatch; //--------------------------- this->HTTP = new TIdHTTP(NULL); this->SSL = new TIdSSLIOHandlerSocketOpenSSL(NULL); this->StreamHTML = new TStringStream(); pmatch = new TStringList; HTTP->AllowCookies = false; HTTP->HandleRedirects = true; HTTP->Request->CustomHeaders->Add(this->Cookies); HTTP->IOHandler = this->SSL; OBJList->Clear(); for (long i = this->ID_from; i <= this->ID_to; i++) { url.sprintf(L"https://localhost/test/%d",i); this->StreamHTML->Clear(); try { HTTP->Get(url, this->StreamHTML); HTTP->Disconnect(); html = this->StreamHTML->DataString; pmatch->Clear(); preg_match_all(html,"...", pmatch); for (int j = 0; j < pmatch->Count; j++) { url.sprintf(L"https://localhost/test/dir/%s",pmatch->Strings[j]); DataList *elm = new DataList; elm->URL = url; elm->STATE = stNormal; try { EnterCriticalSection(§ion); OBJList->Add(elm); this->THRlist->ThreadListUpdate(); } __finally { LeaveCriticalSection(§ion); } } PostMessage(WOwner, WM_THRMESSAGE, 1000, (LPARAM)i); if (Terminated) { PostMessage(WOwner, WM_THRMESSAGE, -1, (LPARAM)this); delete pmatch; break; } }catch(...) { ... } }catch(...) { PostMessage(WOwner,WM_THRMESSAGE, 7003, (LPARAM)this); } } delete pmatch; } void __fastcall THThreadList::ThreadListUpdate(){ try { EnterCriticalSection(§ion); TList *_thList = this->LockList(); int i = 0; String url; int cnt = this->TCount - _thList->Count; while (i < cnt) { MainForm->StatusBarTS4->Panels->Items[0]->Text = cnt; MainForm->StatusBarTS4->Panels->Items[1]->Text = ReconnectList->Count; MainForm->StatusBarTS4->Panels->Items[2]->Text = OList->Count; MainForm->StatusBarTS4->Repaint(); if (ReconnectList->Count > 0) { url = ReconnectList->Strings[0]; ReconnectList->Delete(0); ThreadListAddElement(url); MainForm->addItemListViewTS4("RC", -2, url); }else{ if (OList->Count > 0) { DataList *th = (DataList*) OList->Items[0]; url = th->URL; ThreadListAddElement(url); delete th; OList->Delete(0); MainForm->addItemListViewTS4("IN", 0, url); } } i++; } } __finally{ UnlockList(); LeaveCriticalSection(§ion); } } void __fastcall THThreadList::ThreadListAddElement(String url) { CHThread *chTH = new CHThread(); chTH->URL = url; chTH->Cookies = Cookies; chTH->FreeOnTerminate = false; Add(chTH); chTH->Resume(); } // дочерный поток void __fastcall CHThread::Execute() { String url, html, xml; String fname, cfname; TStringList *pmatch; String outDIR = "..."; //--------------------------- this->HTTP = new TIdHTTP(NULL); this->SSL = new TIdSSLIOHandlerSocketOpenSSL(NULL); this->StreamHTML = new TStringStream(); pmatch = new TStringList; HTTP->AllowCookies = false; HTTP->HandleRedirects = true; HTTP->Request->CustomHeaders->Add(this->Cookies); HTTP->IOHandler = this->SSL; try{ HTTP->Get(this->URL, this->StreamHTML); HTTP->Disconnect(); html = this->StreamHTML->DataString; pmatch->Clear(); preg_match(html,"<textarea\\s+(?:[^>]*)>([^<]*)", pmatch); fname = ""; if (pmatch && pmatch->Count > 0) { xml = smbEncode(pmatch->Strings[0]); fname = ...; this->StreamHTML->SaveToFile(fname); } delete pmatch; PostMessage(WOwner, WM_CTHRMESSAGE, 3000, (LPARAM)this); }catch(Exception &E) { PostMessage(WOwner,WM_CTHRMESSAGE, 7003, (LPARAM)this); } } // ну и обработка сообщений void __fastcall TMainForm::WndProc(TMessage& Message) { ... } else if (Message.Msg == WM_CTHRMESSAGE) { switch (Message.WParam){ case 3000: { ULONG code; CHThread *th = (CHThread*)(Message.LParam); if (GetExitCodeThread(th, &code) && (code == STILL_ACTIVE)) th->WaitFor(); addItemListViewTS4(Message.LParam, 0, "Receive" + th->URL); try { THRcollect->THRlist->LockList(); THRcollect->THRlist->Remove(th); } __finally { THRcollect->THRlist->UnlockList(); } delete th; if (Reconnect) Reconnect = false; try { EnterCriticalSection(§ion); THRcollect->THRlist->ThreadListUpdate(); } __finally { LeaveCriticalSection(§ion); } break; } } ... } |
Сообщ.
#2
,
|
|
|
Надо сделать запись в лог на каждом шаге, будет понятно в каком месте подвисает…
Подозреваю что какие-то из связанных с сетью функций - подвисают по недоступности ресурса или каких-то своих сетевых ошибок. Надо все обращения к сети (в т.ч. запросы DNS и прочее) выносить в отдельный поток. |
Сообщ.
#3
,
|
|
|
Цитата f2065 @ Надо сделать запись в лог на каждом шаге, будет понятно в каком месте подвисает… спс, попробую лог, но думаю, мало он мне даст (подвисание на разных этапах и по времени), хотя... |
Сообщ.
#4
,
|
|
|
... моя ошибка. Спасибо всем.
Цитата Syslik @ void __fastcall THThreadList::ThreadListUpdate(){ ... MainForm->StatusBarTS4->Panels->Items[0]->Text = cnt; MainForm->StatusBarTS4->Panels->Items[1]->Text = ReconnectList->Count; MainForm->StatusBarTS4->Panels->Items[2]->Text = OList->Count; MainForm->StatusBarTS4->Repaint(); if (ReconnectList->Count > 0) { ... MainForm->addItemListViewTS4("RC", -2, url); }else{ ... MainForm->addItemListViewTS4("IN", 0, url); } } } |