C++并發編程之異常安全性增強

在并發編程中,異常安全是一個非常重要的方面,因為并發環境下的錯誤處理比單線程環境更加復雜。當多個線程同時執行時,異常不僅可能影響當前線程,還可能影響其他線程和整個程序的穩定性。以下是一些增強并發程序異常安全性的方法,并附有示例代碼。

1.?異常捕獲和處理

在多線程程序中,每個線程都應該有自己的異常捕獲機制。常見的做法是在每個線程的入口點(如線程函數)中使用?try-catch?塊來捕獲和處理異常。

示例代碼:
#include <iostream>
#include <thread>
#include <exception>void threadFunction() {try {// 模擬可能拋出異常的代碼throw std::runtime_error("An error occurred in the thread");} catch (const std::exception& e) {std::cerr << "Exception caught in thread: " << e.what() << std::endl;// 可以在這里進行日志記錄、資源清理等操作}
}int main() {std::thread t(threadFunction);t.join();return 0;
}

2.?資源管理

使用 RAII(Resource Acquisition Is Initialization)技術來管理資源,確保資源在異常情況下也能正確釋放。C++ 中的智能指針(如?std::unique_ptr?和?std::shared_ptr)和?std::lock_guard?等都是 RAII 的典型應用。

示例代碼:
#include <iostream>
#include <thread>
#include <memory>
#include <mutex>std::mutex mtx;void threadFunction() {try {std::unique_ptr<int> resource(new int(42));std::lock_guard<std::mutex> lock(mtx);// 模擬可能拋出異常的代碼throw std::runtime_error("An error occurred in the thread");} catch (const std::exception& e) {std::cerr << "Exception caught in thread: " << e.what() << std::endl;}
}int main() {std::thread t(threadFunction);t.join();return 0;
}

3.?線程同步

在多線程環境中,確保線程間的同步非常重要。使用互斥鎖、條件變量等同步原語時,要確保在異常情況下不會導致死鎖或資源泄露。

示例代碼:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>std::mutex mtx;
std::condition_variable cv;
bool ready = false;void prepare() {try {std::this_thread::sleep_for(std::chrono::milliseconds(1000));std::lock_guard<std::mutex> lock(mtx);ready = true;cv.notify_one();} catch (const std::exception& e) {std::cerr << "Exception caught in prepare: " << e.what() << std::endl;// 可以在這里進行日志記錄、資源清理等操作}
}void waitAndPrint() {try {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, [] { return ready; });std::cout << "Ready is true" << std::endl;} catch (const std::exception& e) {std::cerr << "Exception caught in waitAndPrint: " << e.what() << std::endl;}
}int main() {std::thread t1(prepare);std::thread t2(waitAndPrint);t1.join();t2.join();return 0;
}

4.?異常傳播

在多線程環境中,異常可能需要從一個線程傳播到另一個線程。可以使用?std::promise?和?std::future?來實現異常的跨線程傳播。

示例代碼:
#include <iostream>
#include <thread>
#include <future>void threadFunction(std::promise<int> promise) {try {// 模擬可能拋出異常的代碼throw std::runtime_error("An error occurred in the thread");promise.set_value(42);} catch (const std::exception& e) {promise.set_exception(std::current_exception());}
}int main() {std::promise<int> promise;std::future<int> future = promise.get_future();std::thread t(threadFunction, std::move(promise));t.join();try {int value = future.get();std::cout << "Value: " << value << std::endl;} catch (const std::exception& e) {std::cerr << "Exception caught in main: " << e.what() << std::endl;}return 0;
}

5.?日志記錄

在多線程程序中,記錄詳細的日志是診斷問題的重要手段。可以使用日志庫(如?spdlog)來記錄日志信息。

示例代碼:
#include <iostream>
#include <thread>
#include <spdlog/spdlog.h>void threadFunction() {try {// 模擬可能拋出異常的代碼throw std::runtime_error("An error occurred in the thread");} catch (const std::exception& e) {spdlog::error("Exception caught in thread: {}", e.what());// 進行其他必要的處理}
}int main() {auto logger = spdlog::stdout_color_mt("console");std::thread t(threadFunction);t.join();return 0;
}

6.?使用線程池

線程池可以更好地管理和復用線程,減少線程創建和銷毀的開銷。線程池通常會處理線程中的異常,并確保線程池的正常運行。

示例代碼:
#include <iostream>
#include <thread>
#include <vector>
#include <queue>
#include <functional>
#include <mutex>
#include <condition_variable>class ThreadPool {
public:ThreadPool(size_t numThreads) : stop(false) {for (size_t i = 0; i < numThreads; ++i) {threads.emplace_back([this] {while (true) {std::function<void()> task;{std::unique_lock<std::mutex> lock(queueMutex);condition.wait(lock, [this] { return stop || !tasks.empty(); });if (stop && tasks.empty()) {return;}task = std::move(tasks.front());tasks.pop();}try {task();} catch (const std::exception& e) {std::cerr << "Exception caught in thread pool: " << e.what() << std::endl;}}});}}~ThreadPool() {{std::unique_lock<std::mutex> lock(queueMutex);stop = true;}condition.notify_all();for (std::thread& t : threads) {t.join();}}template <typename Func, typename... Args>auto enqueue(Func&& func, Args&&... args) -> std::future<decltype(func(args...))> {using return_type = decltype(func(args...));auto task = std::make_shared<std::packaged_task<return_type()>>(std::bind(std::forward<Func>(func), std::forward<Args>(args)...));std::future<return_type> res = task->get_future();{std::unique_lock<std::mutex> lock(queueMutex);if (stop) {throw std::runtime_error("Enqueue on stopped ThreadPool");}tasks.emplace([task]() { (*task)(); });}condition.notify_one();return res;}private:std::vector<std::thread> threads;std::queue<std::function<void()>> tasks;std::mutex queueMutex;std::condition_variable condition;bool stop;
};void simulateWork() {throw std::runtime_error("An error occurred in the task");
}int main() {ThreadPool pool(4);std::future<void> future = pool.enqueue(simulateWork);try {future.get();} catch (const std::exception& e) {std::cerr << "Exception caught in main: " << e.what() << std::endl;}return 0;
}

總結

在并發編程中,確保異常安全需要從多個方面著手,包括異常捕獲和處理、資源管理、線程同步、異常傳播、日志記錄和使用線程池等。通過這些方法,可以有效地處理并發環境中的異常,提高程序的穩定性和可靠性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/66482.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/66482.shtml
英文地址,請注明出處:http://en.pswp.cn/web/66482.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

各語言鏡像配置匯總

鏡像配置匯總 Nodejs [ npm ]Python [ pip ] Nodejs [ npm ] // # 記錄日期&#xff1a;2025-01-20// 查詢當前使用的鏡像 npm get registry// 設置淘寶鏡像 npm config set registry https://registry.npmmirror.com/// 恢復為官方鏡像 npm config set registry https://regi…

Navicat Premium 數據可視化

工作區&#xff0c;數據源以及圖表 數據可視化是使用可視化組件&#xff08;例如圖表&#xff0c;圖形和地圖&#xff09;的信息和數據的圖形表示。 數據可視化工具提供了一種可訪問的方式&#xff0c;用于查看和理解數據中的趨勢&#xff0c;異常值和其他模式。 在Navicat中&…

linux通過web向mac遠程傳輸字符串,mac收到后在終端中直接打印。

要通過Web從Linux向Mac遠程傳輸字符串&#xff0c;并在Mac的終端中直接打印&#xff0c;可以使用以下方法。這里假設Linux作為服務器&#xff0c;Mac作為客戶端。 方法 1&#xff1a;使用Python的HTTP服務器 在Linux上啟動一個簡單的HTTP服務器&#xff0c;Mac通過curl獲取字符…

【系統分享01】Python+Vue電影推薦系統

大家好&#xff0c;作為一名老程序員&#xff0c;今天我將帶你一起走進電影推薦系統的世界&#xff0c;分享如何利用 Django REST Framework 和 Vue 搭建一套完整的電影推薦系統&#xff0c;結合 協同過濾算法&#xff0c;根據用戶評分與影片喜好&#xff0c;精準推送用戶可能喜…

Spring Boot+Vue

Spring BootVue 前后端分離是一種非常流行且高效的開發模式&#xff0c;以下是關于其相關方面的詳細介紹&#xff1a; 前端&#xff08;Vue&#xff09;部分 ? 項目搭建 ? 使用 Vue CLI 創建項目&#xff0c;它提供了豐富的插件和配置選項&#xff0c;能夠快速生成項目基礎…

第十四章:計算機新技術

文章目錄&#xff1a; 一&#xff1a;云計算 二&#xff1a;大數據 三&#xff1a;物聯網 四&#xff1a;人工智能 五&#xff1a;移動網絡與應用 六&#xff1a;電子商務 七&#xff1a;虛擬實現 八&#xff1a;區塊鏈 一&#xff1a;云計算 概念云基于?絡&#xff0…

【大數據2025】MapReduce

MapReduce 基礎介紹 起源與發展&#xff1a;是 2004 年 10 月谷歌發表的 MAPREDUCE 論文的開源實現&#xff0c;最初用于大規模網頁數據并行處理&#xff0c;現成為 Hadoop 核心子項目之一&#xff0c;是面向批處理的分布式計算框架。基本原理&#xff1a;分為 map 和 reduce …

主從復制

簡述mysql 主從復制原理及其工作過程&#xff0c;配置一主兩從并驗證。 主從原理&#xff1a;MySQL 主從同步是一種數據庫復制技術&#xff0c;它通過將主服務器上的數據更改復制到一個或多個從服務器&#xff0c;實現數據的自動同步。 主從同步的核心原理是將主服務器上的二…

【博客之星評選】2024年度前端學習總結

故事的開端...始于2024年第一篇前端技術博客 那故事的終末...也該結束于陪伴了我一整年的前端知識了 踏入 2025 年&#xff0c;滿心激動與自豪&#xff0c;我成功闖進了《2024 年度 CSDN 博客之星總評選》的 TOP300。作為一名剛接觸技術寫作不久的萌新&#xff0c;這次能走到這…

Ubuntu 24.04 LTS 服務器折騰集

目錄 Ubuntu 更改軟件源Ubuntu 系統語言英文改中文windows 遠程鏈接 Ubuntu 圖形界面Windows 通過 openssh 連接 UbuntuUbuntu linux 文件權限Ubuntu 空閑硬盤掛載到 文件管理器的 other locationsUbuntu 開啟 SMB 服務&#xff0c;并通過 windows 訪問Ubuntu安裝Tailscale&am…

《TikTok停服:信息安全警鐘長鳴》

一、TikTok 停服事件回顧 2025 年 1 月 18 日晚&#xff0c;TikTok 通知美國用戶&#xff0c;由于美官方禁令于 19 日起生效&#xff0c;TikTok 軟件將暫時對用戶停止服務。這一消息猶如一顆重磅炸彈&#xff0c;瞬間在全球范圍內掀起軒然大波。美國用戶對此猝不及防&#xff0…

1166 Summit (25)

A summit (峰會) is a meeting of heads of state or government. Arranging the rest areas for the summit is not a simple job. The ideal arrangement of one area is to invite those heads so that everyone is a direct friend of everyone. Now given a set of tenta…

圖論DFS:黑紅樹

我的個人主頁 {\large \mathsf{{\color{Red} 我的個人主頁} } } 我的個人主頁 往 {\color{Red} {\Huge 往} } 往 期 {\color{Green} {\Huge 期} } 期 文 {\color{Blue} {\Huge 文} } 文 章 {\color{Orange} {\Huge 章}} 章 DFS 算法&#xff1a;記憶化搜索DFS 算法&#xf…

C++,設計模式,【目錄篇】

文章目錄 1. 簡介2. 設計模式的分類2.1 創建型模式&#xff08;Creational Patterns&#xff09;&#xff1a;2.2 結構型模式&#xff08;Structural Patterns&#xff09;&#xff1a;2.3 行為型模式&#xff08;Behavioral Patterns&#xff09;&#xff1a; 3. 使用設計模式…

掌握提示詞工程:大模型使用入門指南

掌握提示詞工程&#xff1a;大模型使用入門指南 近年來&#xff0c;大語言模型&#xff08;如 GPT、Claude 等&#xff09;的強大能力令人印象深刻&#xff0c;但要想充分發揮這些模型的潛力&#xff0c;僅僅依靠其預訓練能力還不夠。提示詞工程&#xff08;Prompt Engineerin…

如何使用 useMemo 和 memo 優化 React 應用性能?

使用 useMemo 和 memo 優化 React 應用性能 在構建復雜的 React 應用時&#xff0c;性能優化是確保應用流暢運行的關鍵。React 提供了多種工具來幫助開發者優化組件的渲染和計算邏輯&#xff0c;其中 useMemo 和 memo 是兩個非常有用的 Hook。本文將詳細介紹這兩個工具的使用方…

Agent Laboratory: Using LLM Agents as Research Assistants 論文簡介

加速機器學習研究的智能實驗室——Agent Laboratory 1. 引言 隨著人工智能技術的飛速發展&#xff0c;機器學習領域正以前所未有的速度推進科學發現和技術創新。然而&#xff0c;傳統的科學研究模式往往受到時間、資源和專業知識限制&#xff0c;阻礙了研究者們探索新想法的能…

【網絡協議】【http】【https】ECDHE-TLS1.2

【網絡協議】【http】【https】ECDHE-TLS1.2 ECDHE算法 1.客戶端和服務器端事先確定好使用哪種橢圓曲線&#xff0c;和曲線上的基點G&#xff0c;這兩個參數都是公開的&#xff0c; 雙方各自隨機生成一個隨機數作為私鑰d&#xff0c;并與基點 G相乘得到公鑰Q(QdG)&#xff0c…

規避路由沖突

路由沖突是指在網絡中存在兩個或多個路由器在進行路由選擇時出現矛盾&#xff0c;導致網絡數據包無法正確傳輸&#xff0c;影響網絡的正常運行。為了規避路由沖突&#xff0c;可以采取以下措施&#xff1a; 一、合理規劃IP地址 分配唯一IP&#xff1a;確保每個設備在網絡中都有…

項目實戰--網頁五子棋(游戲大廳)(3)

我們的游戲大廳界面主要需要包含兩個功能&#xff0c;一是顯示用戶信息&#xff0c;二是匹配游戲按鈕 1. 頁面實現 hall.html <!DOCTYPE html> <html lang"ch"> <head><meta charset"UTF-8"><meta name"viewport"…