
C++ mutex přes více funkcí
Dobrý den,
Snažím se udělat dvouvláknovou aplikaci v c++, kde jedno vlákno čte střídavě do dvou bufferů znaky ze souboru a druhé vlákno tyto buffery poté zpracovává. Funguje to celé pomocí eventů. které oboum vláknům říkají, kdy začít s Parsováním bufferu, nebo kdy je možné načítat do bufferu. Přístup k bufferům jsem řešil pomocí mutexů..(viz následující kód)
funkce pro zapisování do bufferu:
void ReadDataFromPath(){
DWORD waitResult;
/*
Pokud je buffer jedna prazdny, pak do nej nahraji data
pozn:. dodelat cestu z argumentu a novou funkci pro nahravani dat
*/
if(bufferOneIsClear == true){
waitResult = WaitForSingleObject(mutexBuffer1, INFINITE);
//if pro kontrolu
cout<<"Plnim buffer 1.."<<endl;
Sleep(5000);
cout<<"Buffer 1 naplnen.."<<endl;
bufferOneIsClear = false;
SetEvent(eventToParse);
ReleaseMutex(mutexBuffer1);
}else if(bufferOneIsClear == false){
waitResult = WaitForSingleObject(mutexBuffer2, INFINITE);
//if pro kontrolu
cout<<"Plnim buffer 2.."<<endl;
Sleep(5000);
cout<<"Buffer 2 naplnen.."<<endl;
bufferOneIsClear = true;
SetEvent(eventToParse);
ReleaseMutex(mutexBuffer2);
}
//abych mohl pokracovat v plneni bufferu
waitResult = WaitForSingleObject(eventToBuffering, INFINITE);
}
funkce pro čtení z bufferu:
void ParseDataFromBuffer(){
DWORD waitResult = WaitForSingleObject( eventToParse, INFINITE);
if(bufferOneIsClear == false){//ctu z bufferu 1
waitResult = WaitForSingleObject( mutexBuffer1, INFINITE);
SetEvent(eventToBuffering);
cout<<"Ctu z bufferu 1.."<<endl;
Sleep(8000); //nahrazuje zatim zpracovani
cout<<"Buffer 1 precten.."<<endl;
ReleaseMutex( mutexBuffer1);
return;
}
if(bufferOneIsClear == true){//ctu z bufferu 2
waitResult = WaitForSingleObject( mutexBuffer2, INFINITE);
SetEvent(eventToBuffering);
cout<<"Ctu z bufferu 2.."<<endl;
Sleep(7000);
cout<<"Buffer 2 precten.."<<endl;
ReleaseMutex(mutexBuffer2);
return;
}
}
Tuto funkci volám ve vláknu jiné třídy:
void ThreadStartUp(){
//while
while(buffers->getContinueProcessing()){
buffers->ParseDataFromBuffer();
}
}
A zde nastává problém, jelikož bych chtěl zpracovávat data ne přímo ve fci getContinueProcessing(), ale v cyklu while, ve kterém je volána. Tím pádem jsem přidal novou funkci na uvolnění mutexu:
void ParseDataFromBufferEnd(){
if(bufferOneIsClear == false){
ReleaseMutex(mutexBuffer1);
return;
}
if(bufferOneIsClear == true){
ReleaseMutex(mutexBuffer2);
return;
}
}
..a předchozí fci getContinueProcessing() jsem pozměnil:
void ParseDataFromBuffer(){
DWORD waitResult = WaitForSingleObject( eventToParse, INFINITE);
//nejaky if
/*
Pokud je naplnen buffer 1 prazdny, pak ctu z bufferu2 a naopak
Ihned pred zahajenim cteni posilam event pro buffer, aby moh pokracovat
v plneni dalsiho bufferu
*/
if(bufferOneIsClear == false){//ctu z bufferu 1
waitResult = WaitForSingleObject( mutexBuffer1, INFINITE);
SetEvent(eventToBuffering);
cout<<"Ctu z bufferu 1.."<<endl;
return;
}
if(bufferOneIsClear == true){//ctu z bufferu 2
waitResult = WaitForSingleObject( mutexBuffer2, INFINITE);
SetEvent(eventToBuffering);
cout<<"Ctu z bufferu 2.."<<endl;
return;
}
}
To vše volám ve while cyklu:
void ThreadStartUp(){
//while
while(buffers->getContinueProcessing()){
buffers->ParseDataFromBuffer();
Sleep(8000);
buffers->ParseDataFromBufferEnd();
}
}
Ačkoliv kód je defacto stejný, jen rozdělený do více funkcí, tak prostě přestal pracovat.. Vlákno na zpracování se prostě už nikdy nezavolá. Chtěl bych se tedy zeptat, jakým způsobem bych to měl rozdělit, nebo co dělám špatně? Nikde na internetu jsem totiž nenašel příklady přío na toto téma.
Děkuji za odpovědi.
A dolezite je aj ze jak mas deklarovane kde presne tie mutexy a tie zbytocne stavove premenne, co je v ktorej triede atd. Preto cely zdrojak a nie chaoticke kusky.
Tvoj problem bude najskor to bufferOneIsClear. Naplnis prvy buffer nastavis to na false, naplnis druhy buffer nastavis to zas na true bez toho aby si vobec vedel ci to uz bolo precitane, a v tom druhom thrade na zaklade toho testujes veci pricom sa ti za jazdy tato premenna moze zmenit. Ziskas mutex1 a potom sa ti zmeni tato premenna za jazdy a neskor na zaklade nej testujes ktory mutex uvolnit??? To je absolutny chaos tak nebezpecny ze az.
a zacni robit to co kazdy slusny vyvojar - NAJPRV na papier albeo v hlave logicky navrh datovych struktur a mutexov a premennych tak aby to nebol nebezpecny chaos meniacich sa veci za jazdy, POTOM zacat pisat kod :)
Povyhadzuj vsetky stavove premenne uplne vsetko zmaz
Alebo
tu sa ti moze za jazdy zmenit bufferOneIsClear
nectes.