Бир иштеке ичинде ката чыкканын кантип текшерсе болот?
AIден жооп
sobes.tech AI
Токтому үчүн, потоктогу кырдаалды текшерүү үчүн, анын түзүлгөн жолуна жана анын натыйжаларын иштетүүгө жараша, бир нече ыкмаларды колдонсо болот:
-
std::futureжанаstd::asyncколдонуу: Эгер потокstd::asyncаркылуу иштетилсе, натыйжаstd::futureобъектисине айланат. Бул объекттеget()жеwait()методдорун чакырганда, потокто ыргытыла турган кырдаал кайра чакырылат.#include <future> #include <iostream> #include <stdexcept> void thread_function() { throw std::runtime_error("Потокто каталар!"); } int main() { std::future<void> future = std::async(std::launch::async, thread_function); try { future.get(); // аяктоону күтүп, кырдаалды ыргытуу } catch (const std::exception& e) { std::cerr << "Потоктон чыккан кырдаал: " << e.what() << std::endl; } return 0; } -
std::promiseжанаstd::futureколдонуу:std::promiseтүздөн-түз потокко өткөрүлүшү мүмкүн же анын сыртында сакталат, ошондо поток кырдаалды сактай алат.#include <future> #include <iostream> #include <thread> #include <stdexcept> void thread_function_with_promise(std::promise<void>&& promise) { try { throw std::runtime_error("Тағы бир каталар!"); promise.set_value(); // маанини орнотуу (эгер кырдаал болбогондо) } catch (...) { promise.set_exception(std::current_exception()); // кырдаалды сактоо } } int main() { std::promise<void> promise; std::future<void> future = promise.get_future(); std::thread t(thread_function_with_promise, std::move(promise)); try { future.get(); // аяктоону күтүп, сакталган кырдаалды ыргытуу } catch (const std::exception& e) { std::cerr << "Потоктон чыккан кырдаал (promise аркылуу): " << e.what() << std::endl; } t.join(); // потоктун аяктоосун күтүү return 0; } -
Куралдуу кырдаалдарды башкаруу: Поток өзүндө кырдаалды кармап, сактай алат (
std::exception_ptrке), же башка потокко анын пайда болушу тууралуу кабарлай алат (атомар өзгөрмө же мьютекс жана шарттуу өзгөрмө аркылуу).#include <iostream> #include <thread> #include <atomic> #include <exception> #include <mutex> #include <condition_variable> std::exception_ptr global_exception_ptr = nullptr; std::mutex exception_mutex; std::condition_variable exception_cv; bool exception_occurred = false; void thread_function_manual() { try { throw std::logic_error("Логикалык каталар!"); } catch (...) { std::lock_guard<std::mutex> lock(exception_mutex); global_exception_ptr = std::current_exception(); // кырдаалды сактоо exception_occurred = true; exception_cv.notify_one(); // күтүп жаткан потокко кабарлоо } } int main() { std::thread t(thread_function_manual); // негизги поток кырдаал тууралуу кабар күтүп турат std::unique_lock<std::mutex> lock(exception_mutex); exception_cv.wait(lock, []{ return exception_occurred; }); if (global_exception_ptr) { try { std::rethrow_exception(global_exception_ptr); // сакталган кырдаалды кайра ыргытуу } catch (const std::exception& e) { std::cerr << "Потоктон чыккан кырдаал (кол менен башкаруу): " << e.what() << std::endl; } } t.join(); return 0; }
Тандоо контекстке жараша болот: std::async жана std::future көбүнесе бөлүнгөн тапшырмадан натыйжа же кырдаалды алуу үчүн ыңгайлуу болсо, std::promise/std::future же кол менен башкаруу көбүрөөк татаал синхрондоо сценарийлеринде пайдалуу болушу мүмкүн.