LINUX.ORG.RU

Выбор архитектуры

 


0

1

Привет всем, Помогите с выбором архитектуры. Использовать исключения или нет, какие есть аргументы за 1 решиение и за 2-е. Скажеться ли использование исключений на производительности?

Решение 1, с пробросом и обработкой исключений. Кажется код проще поддерживать, при этом:

class A {
public:
    std::mutex statusMutex;
    int status;
    std::string error;
    int getStatus() {
        std::unique_lock<std::mutex> lock(statusMutex);
        return status;
    }
    std::string getError() {
        std::unique_lock<std::mutex> lock(statusMutex);
        return error;
    }
    bool doX() {
	try {
		step1();
		// step2(); 
                // step3(); ...
		return true;
	} catch (const std::exception & e) {
	    std::unique_lock<std::mutex> lock(statusMutex);
            status = -1;
	    error = e.what();	
	    return false;
	}
    }
    void step1(){ 
	// ...
	// There has been a breakdown
	throw std::runtime_error ("step1 err");
    }
};

решение 2, без исключений, в плане работы на кодом кажеться не очень удобным из-за if

class A {
public:
    std::mutex statusMutex;
    int status;
    std::string error;
    int getStatus() {
        std::unique_lock<std::mutex> lock(statusMutex);
        return status;
    }
    std::string getError() {
        std::unique_lock<std::mutex> lock(statusMutex);
        return error;
    }
    bool doX() {
	step1();
	if (status == -1) return false;
	// step2(); 
	// if (status == -1) return false;
	// step3(); 
	// if (status == -1) return false;
	// ...
	return true;
    }
    void step1(){ 
	// ...
	// There has been a breakdown
	std::unique_lock<std::mutex> lock(statusMutex);
        status = -1;
	error = "step1 err";	
    }
};

int main() {
	A a;
        std::future<bool> the_a_result = std::async(&A::doX, &a);
	std::cout << "the_a_result = " << the_a_result.get() 
	          << ", a.status = " << a.getStatus() 
		  << ", a.error = '" << a.getError() << "'"
		  << std::endl;
	return 0;
}

Если исключения не превращаются в новый вид ветвления потока выполнения кода, то ничего страшного в них нет. Ну и в твоем случае композиция возвратов из степов может просто уменьшить код и сделать его наглядней, нет смысла проверять результать возврата по каждому степу чтобы принять решение что делать дальше если система приводится в несогласованное состояние при неправильной работе любого из степов.

abcq ★★ ()
Ответ на: комментарий от cvprog

Тогда проблем особо нет, и вы только размером приложения платите, а не производительностью.

sanwashere ★★ ()

Никакой архитектурой тут даже не пахнет. Зачем мьютекс для int? Используй atomic. Исключения делают код чище и отделяют логику от обработки ошибок, их специально для этого и сделали.

LZai ()
Ответ на: комментарий от cvprog

Ну да с int-ом atomic. Поспешил .. но это модельный пример.

там с интом даже атомик не нужен.

атомики и мьютексты - это для мультиредовой работы, когда могут пересечься во времени операции изменения нечта промеж собой и/или изменения и чтения. если по естественным причинам такие операции не пересекаются, то ни мьютексы ни атомики не нужны.

если даже один тред бросает исключение, а другой его обрабатывает, тут нет пересечения по времени, поскольку обьект исключения будет создан целиком в один момент времени, а станет доступен на чтение в совсем другой. вы не сможете пробросить недосформированный обьект исключения. так что даже атомики там не нужны, если потом оно только читается.

базовый принцип обработки ошибок прост и естественнен - ошибка должна быть обработана как можно ближе к контексту ее возникновения. какая-нибудь функция open_file(..) должна возвращать успех или ошибку операции, а не бросать исключение, если файла например такого нет.

необходимость исключений как общего механизма возникает тогда, когда ошибку НЕВОЗМОЖНО обработать в данном контексте, и даже в некоей разумной области текущего контекста, а также ее невозможно устранить. то есть возникает ИСКЛЮЧИТЕЛЬНАЯ с точки зрения БАЗОВОГО ПРИНЦИПА ситуация и именно она порождает необходимость исключений. Обычно такие исключение обрабатывают на самом верху, а программа считается находящейся в невосстановимом состоянии и или заверщается с диагностикой или перезапускается. в любом случае исключение это не средство регулярного программирования, а средство ловли багов, сбойных ситуаций и прочих недочетов. нормальный софт вообще не должен порождать исключений.

alysnix ()
Ответ на: комментарий от alysnix

нормальный софт вообще не должен порождать исключений.

Я для обработки критических ошибок в одном месте использую исключения. Сильно сократился код. Критические ошибки - далее работа метода точно не возможна.

cvprog ()
Ограничение на отправку комментариев: только для зарегистрированных пользователей