Nie, program w czasie działania odpala wątek, w którym wykonuje obliczenia. Wewnątrz tego wątku jest tworzony kolejny.
Trzymam sobie to wszystko na stosie, ponieważ chce dodać właśnie przerwanie wykonywania wątków i powrót do głównego.
Wszystko klepie w embarcadero xe3, dlatego też mam dostęp tylko do Boost 1.39, chyba że, źle doczytałem i można jakimś cudem dołączyć nowszą wersje.
Kod wątku:
Kopiuj
void searchButtonThread()
{
try{
boost::this_thread::interruption_point();
while(!Form4->HandleAllocated());
boost::mutex mutex_;
boost::mutex::scoped_lock lock(mutex_);
boost::this_thread::interruption_point();
using namespace searchRap;
std::vector<TAB> newData;
SEARCH_FILTER * filterStatus = new SEARCH_FILTER;
ErrorMsg->SetHWND(Form4->Handle);
boost::this_thread::interruption_point();
if (Form1->PageControl1->ActivePageIndex == 0)
{
Form1->CheckFilters(filterStatus, 0);
PrepareRap * newRaport;
newRaport = new PrepareRap(filterStatus);
if (!(filterStatus->bSearch || filterStatus->bSort))
{
if (GenRap->allRap.size() != 0)
{
Form1->ReloadDataBC_DAM(GenRap->allRap, 0);
}else if (GenRap->allRap.size() == 0)
{
ErrorMsg->SendMessageA("B��d �adowania danych", true);
ErrorMsg->ShowWindowMsg();
}
}else
{
if (!(newRaport->PutData(GenRap->allRap)))
{
ErrorMsg->SendMessageA("B��d �adowania danych", true);
ErrorMsg->ShowWindowMsg();
}
else
newRaport->StartSearch();
boost::this_thread::interruption_point();
if (!(newRaport->ThrowData(newData)))
{
Form1->ReloadDataBC_DAM(GenRap->allRap, 0);
ErrorMsg->SendMessageA("Brak danych do wy�wietlenia, wed�ug podanych parametr�w!", true);
ErrorMsg->ShowWindowMsg();
}
else
{
for (int x = Form1->StringGrid1->RowCount; x > 0; x--)
Form1->StringGrid1->Rows[x]->Clear();
Form1->StringGrid1->RowCount = NewRowNumb+1;
Form1->ReloadDataBC_DAM(newData, 1, 0);
}
}
delete newRaport;
boost::this_thread::interruption_point();
}else if (Form1->PageControl1->ActivePageIndex == 1)
{
boost::this_thread::interruption_point();
Form1->CheckFilters(filterStatus, 1);
PrepareRap * newRaport;
newRaport = new PrepareRap(filterStatus);
sr_for_measure::CPreRapForMeasure newRapMeasure(filterStatus);
if (!(filterStatus->bSearch || filterStatus->bSort || filterStatus->bMS_Flag))
{
if (GenRap->allRap.size() > 0)
{
Form1->ReloadDataBC_DAM(GenRap->allRap, 0, 1);
}else if (GenRap->allRap.size() == 0)
{
ErrorMsg->SendMessageA("B��d �adowania danych", true);
ErrorMsg->ShowWindowMsg();
}
}else
{
Form1->GetInfoRap(1);
GenRap->allRap.clear();
GenRap->newData.clear();
for (unsigned int i = 0; i < GenRap->archRapStruc.size(); i++)
{
GenRap->allRap.push_back(GenRap->archRapStruc[i].karta_sp3);
}
if (filterStatus->bSearch || filterStatus->bSort)
{
if (!(newRaport->PutData(GenRap->allRap)))
{
ErrorMsg->SendMessageA("B��d �adowania danych", true);
ErrorMsg->ShowWindowMsg();
}
else
{
newRaport->StartSearch();
}
GenRap->newData.clear();
if (!(newRaport->ThrowData(GenRap->newData)))
{
ErrorMsg->SendMessageA("Brak danych do wy�wietlenia, wed�ug podanych parametr�w!", true);
ErrorMsg->ShowWindowMsg();
}
}
if (!GenRap->newData.empty())
{
newRapMeasure.PutData(GenRap->newData);
std::vector<TAB*> tempVtab = GenRap->retPointers(GenRap->newData);
}
else if (!GenRap->allRap.empty())
{
newRapMeasure.PutData(GenRap->allRap);
std::vector<TAB*> tempVtab = GenRap->retPointers(GenRap->allRap);
}
newRapMeasure.StartSearch(1);
newRapMeasure.ThrowData();
boost::this_thread::interruption_point();
for (int x = Form1->StringGrid2->RowCount; x > 0; x--)
Form1->StringGrid2->Rows[x]->Clear();
Form1->StringGrid2->RowCount = NewRowNumb+1;
Form1->ReloadDataBC_DAM(GenRap->newData, 1, 1);
GenRap->dataIt = GenRap->newData.begin();
}
delete newRaport;
boost::this_thread::interruption_point();
}else if (Form1->PageControl1->ActivePageIndex == 2)
{
boost::this_thread::interruption_point();
Form1->CheckFilters(filterStatus, 2);
PrepareRap * newRaport;
newRaport = new PrepareRap(filterStatus);
sr_for_measure::CPreRapForMeasure newRapMeasure(filterStatus);
if (!(filterStatus->bSearch || filterStatus->bSort || filterStatus->bMS_Flag))
{
if (GenRap->allRap.size() != 0)
{
GenRap->dataIt = GenRap->allRap.begin();
Form1->ReloadDataBC_DAM(GenRap->allRap, 0, 2);
}else if (GenRap->allRap.size() == 0)
{
ErrorMsg->SendMessageA("B��d �adowania danych", true);
ErrorMsg->ShowWindowMsg();
}
}else
{
GenRap->newData.erase(GenRap->newData.begin(), GenRap->newData.end());
Form1->GetInfoRap(1);
if (!(newRaport->PutData(GenRap->allRap)))
{
ErrorMsg->SendMessageA("B��d �adowania danych", true);
ErrorMsg->ShowWindowMsg();
}
else
{
newRaport->StartSearch();
}
GenRap->newData.clear();
if (!(newRaport->ThrowData(GenRap->newData)))
{
ErrorMsg->SendMessageA("Brak danych do wy�wietlenia, wed�ug podanych parametr�w!", true);
ErrorMsg->ShowWindowMsg();
}
if (!GenRap->newData.empty())
{
newRapMeasure.PutData(GenRap->newData);
}
else if (!GenRap->allRap.empty())
{
newRapMeasure.PutData(GenRap->allRap);
}
boost::this_thread::interruption_point();
newRapMeasure.StartSearch(2);
newRapMeasure.ThrowData();
boost::this_thread::interruption_point();
for (int x = Form1->StringGrid3->RowCount; x > 0; x--)
Form1->StringGrid3->Rows[x]->Clear();
Form1->StringGrid3->RowCount = NewRowNumb+1;
Form1->ReloadDataBC_DAM(GenRap->newData, 1, 2);
GenRap->dataIt = GenRap->newData.begin();
}
delete newRaport;
boost::this_thread::interruption_point();
}
boost::this_thread::interruption_point();
Form1->DS_FRow = NewRowNumb;
delete filterStatus;
while(!GenRap->READY_FORM);
Form4->Close();
GenRap->READY_FORM = false;
ErrorMsg->SetHWND();
boost::this_thread::interruption_point();
}catch(const boost::thread_interrupted&)
{
}
};
Wywołanie wątku:
Kopiuj
void __fastcall TForm1::SetFilterClick(TObject *Sender)
{
if (Form4 == NULL)
Form4 = new TForm4(Application);
if (Form4 != NULL)
{
boost::thread * searchButtonTh = new boost::thread(searchButtonThread);
GenRap->STACK_THREAD_POINTER.push(searchButtonTh);
boost::this_thread::yield();
Form4->ShowModal();
try
{
if (searchButtonTh->joinable())
searchButtonTh->join();
}catch(...)
{
}
if (!GenRap->STACK_THREAD_POINTER.empty())
GenRap->STACK_THREAD_POINTER.pop();
delete searchButtonTh;
Button10->Enabled = false;
}
}
Ubijanie wątku:
Kopiuj
void __fastcall TForm4::Button1Click(TObject *Sender)
{
boost::xtime xt;
boost::xtime_get(&xt, boost::TIME_UTC);
xt.sec += 5;
unsigned int stackSize = GenRap->STACK_THREAD_POINTER.size();
for (unsigned int i = 0; i < stackSize; i++)
{
while (GenRap->STACK_THREAD_POINTER.top()->timed_join(boost::posix_time::seconds(2))==false)
GenRap->STACK_THREAD_POINTER.top()->interrupt();
GenRap->STACK_THREAD_POINTER.pop();
}
Form4->Close();
Timer1->Enabled = false;
}
Na pewno jest mnóstwo błędów w tym fragmencie. Niestety gubię się pod presją czasu, co nie pozwala mi panować nad kodem tak jak bym chciał.
Mam nadzieje, że nie zostanę zbesztany przez tak ohydny kod :P
PS. Tak w ogóle, to witam całą społeczność 4p. Siedzę co prawda na forum od dosyć dawna, aczkolwiek czytając zazwyczaj ciekawe tematy.
Z tak małym skillem, wolę nie wylewać swoich mądrości :P