Boost Thread i przerwanie wątku

0

Mam pytanie dotyczące przerywania wątku, funkcją interrupt().
Przerwanie działa, natomiast gdy kod dochodzi do metody join() wisi w nieskończoność.

Doszedłem do tego, że prawdopodobnie oczekuje na wykonanie wątku, ale wcześniej został przerwany.

Próbowałem to ominąć w taki sposób:

if (!pageControlTh->interruption_requested())
	pageControlTh->join();
else
	pageControlTh->detach();

Pierwsze przerwanie działa, natomiast gdy niszcze wątek, następnie tworze na nowo, to kolejne przejście wchodzi poprawnie w join, bo nie było przerwania, natomiast znowu wisi.

Zwiesza sie dokładnie w momencie wywołania tego fragmentu:

boost::this_thread::interruptible_wait(void *,boost::detail::timeout)

Zmieniłem trochę kod, wzorowałem się na tej stronce
https://www.quantnet.com/threads/c-multithreading-in-boost.10028/

teraz utyka mi wszystko na pętli while.

Co może być powodem tego?

unsigned int stackSize = STACK_THREAD_POINTER.size();
for (unsigned int i = 0; i < stackSize; i++)
{
while (STACK_THREAD_POINTER.top()->timed_join(boost::posix_time::seconds(2))==false)
	STACK_THREAD_POINTER.top()->interrupt();

	STACK_THREAD_POINTER.pop();
}
0

Przede wszystkim napisz co chcesz zaimplementować - pulę wątków?
Po drugie timed_join() jest deprecated, używaj try_join_for()/try_join_until() - http://www.boost.org/doc/libs/1_54_0/doc/html/thread/thread_management.html#thread.thread_management.tutorial.join
Pokaż kod wątku.

0

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:

void searchButtonThread()
{
try{
boost::this_thread::interruption_point();
	while(!Form4->HandleAllocated());
//	bool mutexBool;
	boost::mutex mutex_;
	boost::mutex::scoped_lock lock(mutex_);


/*
	if (boost::this_thread::interruption_enabled())
		Form9->Label2->Caption = "Enabled1";
	else
		Form9->Label2->Caption = "Disabled1";

	if (boost::this_thread::interruption_requested())
		Form9->Label5->Caption = "Enabled1";
	else
		Form9->Label5->Caption = "Disabled1";
*/
boost::this_thread::interruption_point();
		using namespace searchRap;
		std::vector<TAB> newData;
		SEARCH_FILTER * filterStatus = new SEARCH_FILTER;                       //ustawienia filtr�w

		ErrorMsg->SetHWND(Form4->Handle);

boost::this_thread::interruption_point();
		if (Form1->PageControl1->ActivePageIndex == 0)
		{
			Form1->CheckFilters(filterStatus, 0);                               //sprawdzenie filtr�w na formatce

			PrepareRap * newRaport;
			newRaport = new PrepareRap(filterStatus);                                     //nowy obiekt wyszukiwania

			if (!(filterStatus->bSearch || filterStatus->bSort))                    //je�eli bark filtr�w to za�aduj na nowo dane
			{
				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)))                           //wrzu� dane do obiektu z tablicy
				{
					ErrorMsg->SendMessageA("B��d �adowania danych", true);
					ErrorMsg->ShowWindowMsg();
				}
				else
					newRaport->StartSearch();                                        //zacznij szuka�
boost::this_thread::interruption_point();
				if (!(newRaport->ThrowData(newData)))                                //wypluj dane do tablicy
				{
					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();                          //wyczy�� grida

					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)) //je�eli bark filtr�w to za�aduj na nowo dane
			{
				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)))                           //wrzu� dane do obiektu z tablicy
					{
						ErrorMsg->SendMessageA("B��d �adowania danych", true);
						ErrorMsg->ShowWindowMsg();
					}
					else
					{
						newRaport->StartSearch();                                        //zacznij szuka�
					}
					GenRap->newData.clear();
					if (!(newRaport->ThrowData(GenRap->newData)))                                //wypluj dane do tablicy
					{
						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);

//						GenRap->NewTypeSearch->GetTypeList(tempVtab);
//						GenRap->NewAreaSearch->GetAreaList(tempVtab);
					}
					else if (!GenRap->allRap.empty())
					{
						newRapMeasure.PutData(GenRap->allRap);

						std::vector<TAB*> tempVtab = GenRap->retPointers(GenRap->allRap);

//						GenRap->NewTypeSearch->GetTypeList(tempVtab);
//						GenRap->NewAreaSearch->GetAreaList(tempVtab);
					}

/*	if (boost::this_thread::interruption_enabled())
		Form9->Label2->Caption = "Enabled5";
	else
		Form9->Label2->Caption = "Disabled5";

	if (boost::this_thread::interruption_requested())
		Form9->Label5->Caption = "Enabled5";
	else
		Form9->Label5->Caption = "Disabled5";
*/
					newRapMeasure.StartSearch(1);
					newRapMeasure.ThrowData();
boost::this_thread::interruption_point();
					for (int x = Form1->StringGrid2->RowCount; x > 0; x--)
							Form1->StringGrid2->Rows[x]->Clear();                          //wyczy�� grida

					Form1->StringGrid2->RowCount = NewRowNumb+1;

					Form1->ReloadDataBC_DAM(GenRap->newData, 1, 1);
					GenRap->dataIt = GenRap->newData.begin();
			}
			delete newRaport;   //access violation
			boost::this_thread::interruption_point();

/*	if (boost::this_thread::interruption_enabled())
		Form9->Label2->Caption = "Enabled6";
	else
		Form9->Label2->Caption = "Disabled6";

	if (boost::this_thread::interruption_requested())
		Form9->Label5->Caption = "Enabled6";
	else
		Form9->Label5->Caption = "Disabled6";
*/
		}else if (Form1->PageControl1->ActivePageIndex == 2)
		{
boost::this_thread::interruption_point();
			Form1->CheckFilters(filterStatus, 2);                                             //sprawdzenie filtr�w na formatce
			PrepareRap * newRaport;
			newRaport = new PrepareRap(filterStatus);                                     //nowy obiekt wyszukiwania
			sr_for_measure::CPreRapForMeasure newRapMeasure(filterStatus);

			if (!(filterStatus->bSearch || filterStatus->bSort || filterStatus->bMS_Flag)) //je�eli bark filtr�w to za�aduj na nowo dane
			{
			//=========================================
				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);

//				GenRap->NewTypeSearch->GetTypeList(GenRap->retPointers(GenRap->allRap));
//				GenRap->NewAreaSearch->GetAreaList(GenRap->retPointers(GenRap->allRap));

				if (!(newRaport->PutData(GenRap->allRap)))                           //wrzu� dane do obiektu z tablicy
				{
					ErrorMsg->SendMessageA("B��d �adowania danych", true);
					ErrorMsg->ShowWindowMsg();
				}
				else
				{
					newRaport->StartSearch();                                        //zacznij szuka�
				}
                GenRap->newData.clear();
				if (!(newRaport->ThrowData(GenRap->newData)))                                //wypluj dane do tablicy
				{
					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();                          //wyczy�� grida

					Form1->StringGrid3->RowCount = NewRowNumb+1;

					Form1->ReloadDataBC_DAM(GenRap->newData, 1, 2);

					GenRap->dataIt = GenRap->newData.begin();
			}
			delete newRaport;
			boost::this_thread::interruption_point();
		}

/*	if (boost::this_thread::interruption_enabled())
		Form9->Label2->Caption = "Enabled2";
	else
		Form9->Label2->Caption = "Disabled2";

	if (boost::this_thread::interruption_requested())
		Form9->Label5->Caption = "Enabled2";
	else
		Form9->Label5->Caption = "Disabled2";
*/
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&)
{
//	Form9->Label5->Caption = "Enabled";
//	throw(ex);
}
};
//------------------------------------------------------------------------------ 

Wywołanie wątku:

void __fastcall TForm1::SetFilterClick(TObject *Sender)                         //button filtrowania
{  																			    /////////////////////

	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();
//			else
//				searchButtonTh->detach();
}catch(...)
{
//	Form9->Label8->Caption = "exception";
}

		if (!GenRap->STACK_THREAD_POINTER.empty())
			GenRap->STACK_THREAD_POINTER.pop();

		delete searchButtonTh;

		Button10->Enabled = false;
	}
} 

Ubijanie wątku:

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

1 użytkowników online, w tym zalogowanych: 0, gości: 1