▼Прихований текст
-=ЮрА=- написав:І куди ви мої івенти забрали?
- замінив їх на мьютекси (тіж івенти тільки з автосбросом), я взагалі вам синхронізацію демоснтрував, проте втикніть туди свою івенту(це на касається основної теми яку ви затронули, я навів вам приклад де ще окрім стейту батону обходимо дедлок при синхронізації при обвалі треди,а це куди критичніша помилка ніж активність елемнту гуі). Як какзав Геракліт "досить слів...", тому ось вам приклад з батонами
#include <iostream>
#include <thread>
#include <mutex>
#include <string>
std::mutex g_pages_mutex;
class cButtonEmul{
protected:
bool bState;
public:
cButtonEmul(bool bState = true){
cButtonEmul::bState = bState;
}
bool getState(){return bState;}
bool setState(bool bState){
cButtonEmul::bState = bState;
}
};
struct sThreadParam{
std::string *url;
cButtonEmul *btn;
};
void save_page(const sThreadParam ¶m)
{
if( param.btn )
param.btn->setState(false);
g_pages_mutex.lock();
try
{
try
{
if( param.url ){
if( param.url->find("thrd2", 0) != std::string::npos )
throw "I'm naipnulosya";
else
if( param.url->find("thrd1", 0) != std::string::npos )
throw 0;
else
*param.url = "fake content";
}
}
catch(const char * msg){
if( param.url )
*param.url = msg;
}
}
catch(...){
g_pages_mutex.unlock();
if( param.url )
*param.url = "unhandled exception occured!";
if( param.btn )
param.btn->setState(true);
return;//àâàð³éíèé âèõ³ä
}
g_pages_mutex.unlock();
if( param.btn )
param.btn->setState(true);
}
int main()
{
cButtonEmul btn1(false);std::string sDownload1 = "http://thrd1URL";
cButtonEmul btn2(false);std::string sDownload2 = "http://thrd2URL";
cButtonEmul btn3(false);std::string sDownload3 = "http://thrd3URL";
sThreadParam prm1 = {&sDownload1, &btn1};
sThreadParam prm2 = {&sDownload2, &btn2};
sThreadParam prm3 = {&sDownload3, &btn3};
std::thread t1(save_page, prm1);
std::thread t2(save_page, prm2);
std::thread t3(save_page, prm3);
t1.join();
t2.join();
t3.join();
g_pages_mutex.lock();
std::cout<< sDownload1 <<" btn1 state : "<<std::string(btn1.getState() ? "enabled" : "disabled")<<std::endl;
std::cout<< sDownload2 <<" btn2 state : "<<std::string(btn2.getState() ? "enabled" : "disabled")<<std::endl;
std::cout<< sDownload3 <<" btn3 state : "<<std::string(btn3.getState() ? "enabled" : "disabled")<<std::endl;
g_pages_mutex.unlock();
return 0;
}
http://ideone.com/sA0aDG
unhandled exception occured! btn1 state : enabled - той трай якраз відпрацьовує щось зовсім несподіване. Як бачите ніякого файналі не потрібно.
по суті тут finally зроблений, як try catch із дубльованим кодом, який мав міститись у finally. мінуси цього варіанту у тому що він не підтримує return’и у try catch. але фіг з ними.
це, звичайно, варіант, але це вносить незручності... нє ну маємо що маємо, але все одно не розумію чому вони такі жадні на конструкцію try finall...
П. С. перерив інші форуми — переносимого рішення по емуляції try finally немає.