C++手撕共享指針、多線程交替、LRU緩存

?1.?共享指針

#include <atomic>
#include <iostream>template <typename T> class sharedptr {
private:T *ptr;std::atomic<size_t> *count;public:sharedptr(T *p) : ptr(p), count(new std::atomic<size_t>(1)) {}sharedptr(const sharedptr &other) : ptr(other.ptr), count(other.count) {(*count)++;}sharedptr(sharedptr &&other) : ptr(other.ptr), count(other.count) {other.ptr = nullptr;other.count = nullptr;}// 拷貝賦值運算符// 何時調用?當用一個 ?已存在的對象(左值)?// 賦值給另一個已存在的對象時: Myclass a,b;sharedptr &operator=(const sharedptr &other) {if (this != &other) {release();ptr = other.ptr;count = other.count;(*count)++;}return *this;}// 移動賦值運算符sharedptr &operator=(sharedptr &&other) {if (this != &other) {ptr = other.ptr;count = other.count;other.ptr = nullptr;other.count = nullptr;}return *this;}void release() {if (count != nullptr && (--(*count)) == 0) {delete ptr;delete count;}}~sharedptr() { release(); }T *operator->() { return ptr; }T &operator*() { return *ptr; }
};
int main() {}

1. 快速記憶

  1. ?雙成員結構

    • T* ptr管理資源
    • atomic<size_t>* count保證線程安全
  2. ?五大特殊函數

    // 1. 構造
    explicit Shared_Ptr(T* p = nullptr)// 2. 拷貝構造
    Shared_Ptr(const Shared_Ptr&)// 3. 移動構造(noexcept優化)
    Shared_Ptr(Shared_Ptr&&) noexcept// 4. 拷貝賦值(自檢+釋放舊值:等號左)
    operator=(const Shared_Ptr&)// 5. 移動賦值(自檢+釋放舊值:等號右)
    operator=(Shared_Ptr&&) noexcept
  3. 建議手寫時按以下順序實現

    • 成員變量

    • 構造函數
    • 拷貝構造/賦值
    • 移動構造/賦值
    • 析構函數
    • 操作符重載
    • 輔助方法

2. 多線程交替打印

代碼:

#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>int m;
std::mutex mtx;
std::condition_variable cv;
void print(int target) {for (int i = 0; i < 10; i++) {// 這行代碼相當重要std::unique_lock<std::mutex> lock(mtx);// 條件謂詞不接受參數cv.wait(lock, [&]() { return m == target; });std::cout << m << std::endl;m = (m + 1) % 3;cv.notify_all();}
}
int main() {m = 0;std::thread t1(print, 0);std::thread t2(print, 1);std::thread t3(print, 2);t1.join();t2.join();t3.join();
}

1. std::unique_lock<std::mutex>對象lock和std::mutex對象mtx是什么關系?

std::unique_lock<std::mutex> 是一個管理互斥量(std::mutex)的 RAII(資源獲取即初始化)包裝器。兩者的關系如下:

  • 綁定關系:當你創建一個 std::unique_lock<std::mutex> 對象時,通常會將一個 std::mutex 對象(比如 mtx)傳遞給它。此時,unique_lock 會自動嘗試鎖定這個互斥量。

  • 自動管理unique_lock 在其生命周期內擁有并管理這個 mtx 的鎖定狀態。當 unique_lock 對象銷毀時(例如超出作用域),它會自動解鎖 mtx,避免手動解鎖帶來的錯誤風險。

  • 靈活性:與 std::lock_guard 相比,unique_lock 提供了更多的靈活性,比如能夠延遲鎖定、手動解鎖或重新鎖定,以及支持條件變量等待時的鎖管理。

  • 個人理解:所謂mutex(mutual exclusion),本身僅是聲明了一個互斥量,此時并不包含鎖的意義

2. 簡述一下cv.wait和notify做了什么?

  • cv.wait

    • 等待與解鎖:調用 cv.wait(lock, predicate) 時,線程會進入等待狀態,同時自動釋放傳入的 std::unique_lock 持有的互斥量。這使得其他線程可以獲得該互斥量,從而修改共享數據。

    • 阻塞與恢復:當等待的條件(通常由傳入的 lambda 表達式 predicate 檢查)不滿足時,線程會一直阻塞。待其他線程調用 notify 方法后,等待線程會被喚醒并重新嘗試獲取鎖,隨后檢查條件,直到條件滿足為止。

  • notify

    • 喚醒等待線程cv.notify_one() 會喚醒一個正等待此條件變量的線程,而 cv.notify_all() 則會喚醒所有等待的線程。

    • 同步機制:當某個線程修改了共享數據并滿足了等待線程所期望的條件后,它會調用 notify 方法通知等待線程,促使它們從阻塞狀態中恢復,繼續執行。

3. LRU緩存

class LRUCache {
private:int capacity;list<pair<int,int>> mylist;unordered_map<int,list<pair<int,int>>::iterator> umap;
public:LRUCache(int capacity):capacity(capacity) {}int get(int key) {if(umap.find(key)==umap.end())  {return -1;}int value=umap[key]->second;mylist.erase(umap[key]);mylist.push_front({key,value});umap[key]=mylist.begin();return value;}void put(int key, int value) {if(umap.find(key)!=umap.end()){mylist.erase(umap[key]);mylist.push_front({key,value});umap[key]=mylist.begin();}   else{if(umap.size()==capacity){//  不能直接刪除end()// umap.erase(mylist.end());int old_key=mylist.back().first;umap.erase(old_key);mylist.pop_back();}mylist.push_front({key,value});umap[key]=mylist.begin();}}
};  

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

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

相關文章

新版 eslintrc 文件棄用 .eslintignore已棄用 替代方案

1.進入eslint.config.mjs文件 2.import { defineConfig, globalIgnores } from "eslint/config"; 引入globalIgnores 3.配置 defineConfig([ ... globalIgnores([ "config/*", ".husky", ".local", "public/*", ".…

基于ngnix配置本地代理到對應服務器

遇到的問題&#xff1a;服務器可以訪問到的地址&#xff0c;我本地代碼無法訪問到 在服務器上裝好nginx&#xff0c;在nginx配置文件nginx.conf中配置本地想要鏈接對應的服務器端口信息 server {listen 8101;location / {proxy_http_version 1.1;proxy_set_header Upgrade $h…

Go 語言 fmt 模塊的完整方法詳解及示例

以下是 Go 語言 fmt 模塊的完整方法詳解及示例&#xff0c;涵蓋所有核心功能&#xff1a; 一、輸出函數 將數據寫入標準輸出、文件或字符串。 1. Print / Println / Printf 功能 Print: 寫入標準輸出&#xff0c;不換行。Println: 寫入標準輸出并換行。Printf: 格式化寫入標…

在K8S中使用ArgoCD做持續部署

一、了解argocd ArgoCD是一個基于Kubernetes的GitOps持續交付工具&#xff0c;應用的部署和更新都可以在Git倉庫上同步實現&#xff0c;并自帶一個可視化界面。本文介紹如何使用GitArgocd方式來實現在k8s中部署和更新應用服務。關于ci這一塊這里不多介紹。主要講解argocd如何實…

可視化圖解算法:刪除有序(排序)鏈表中重復的元素

1. 題目 描述 刪除給出鏈表中的重復元素&#xff08;鏈表中元素從小到大有序&#xff09;&#xff0c;使鏈表中的所有元素都只出現一次 例如&#xff1a; 給出的鏈表為1→1→2,返回1→2. 給出的鏈表為1→1→2→3→3返回1→2→3. 數據范圍&#xff1a;鏈表長度滿足 0≤n≤100…

ETL:數據清洗、規范化和聚合的重要性

在當今這個數據呈爆炸式增長的時代&#xff0c;數據已成為企業最為寶貴的資產之一。然而&#xff0c;數據的海量增長也伴隨著諸多問題&#xff0c;如數據來源多樣、結構復雜以及質量問題等&#xff0c;這些問題嚴重阻礙了數據的有效處理與深度分析。在此背景下&#xff0c;ETL&…

spring boot jwt生成token

1、引入jwt依賴 <!--jwt的依賴--> <dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.18.3</version> </dependency> 2、創建TokenUtils工具類 package com.pn.utils;import com.…

豪越科技:融合低空經濟的消防一體化安全管控解決方案

在科技飛速發展的當下&#xff0c;2025 年低空經濟正處于規模化商用的關鍵節點&#xff0c;其在應急救援、物流配送等多領域展現出巨大潛力。豪越科技憑借其先進的消防一體化安全管控方案&#xff0c;與低空經濟深度融合&#xff0c;打造出一套更為高效、智能的消防解決方案&am…

清華大學 | DeepSeek第十版!《DeepSeek政務應用場景及解決方案》

清華大學發布的《DeepSeek政務應用場景及解決方案》研究報告&#xff0c;聚焦人工智能技術DeepSeek在政府治理與公共服務中的創新實踐&#xff0c;系統闡述了其如何通過智能化技術賦能政務數字化轉型&#xff0c;推動治理能力現代化。報告指出&#xff0c;DeepSeek作為融合大數…

R語言雙Y軸折線圖+相關性注釋

目錄 包和數據 作圖代碼及詳解 包和數據 rm(list ls()) library(ggpubr) library(scales) library(ggplot2)data <- iris##鳶尾花數據集 data1 <- data[1:30,c(1,2,3)] > head(data1)Sepal.Length Sepal.Width Petal.Length 1 5.1 3.5 …

Android Compose 框架隱式動畫之過渡動畫深入剖析(二十六)

Android Compose 框架隱式動畫之過渡動畫深入剖析 一、引言 在移動應用開發領域&#xff0c;用戶體驗始終是至關重要的。動畫效果作為提升用戶體驗的關鍵元素&#xff0c;能夠為應用增添生動性和交互性。Android Compose 作為現代 Android UI 工具包&#xff0c;為開發者提供…

sql server如何提高索引命中率

#新星杯14天創作挑戰營第9期# 前言 近期發現以前開發的系統運行緩慢&#xff0c;經排查&#xff0c;發現有很大的優化空間。數據庫版本使用的是sql server&#xff0c;主要有以下一些問題點&#xff1a;數據表無索引、一些不規范的寫法&#xff08;例如in、大表關聯&#xff0…

Qt進程間通信:QSharedMemory 使用詳解

1. 什么是 QSharedMemory&#xff1f; QSharedMemory 是 Qt 中用于進程間共享內存的類。它允許多個進程共享一塊內存區域&#xff0c;從而避免數據傳輸時的 IO 操作&#xff0c;提高通信速度。通過共享內存&#xff0c;多個進程可以直接讀寫這塊內存&#xff0c;而無需經過文件…

2024年3月全國計算機等級考試真題(二級C語言)

&#x1f600; 第1題 下列敘述中正確的是 A. 矩陣是非線性結構 B. 數組是長度固定的線性表 C. 對線性表只能作插入與刪除運算 D. 線性表中各元素的數據類型可以不同 題目解析&#xff1a; A. 矩陣是非線性結構 錯誤。矩陣通常是二維數組&#xff0c;屬…

基于Ebay拍賣網站成交價格的影響因素分析

摘要:近些年來網上拍賣的不斷地發展&#xff0c;網上購物慢慢變成了大家普遍接受的購物方式。因此關于網上拍賣的研究日益成為很多人研究的重點。 影響拍賣網站價格的因素很多&#xff0c;但很少有人分得清楚哪些因素才是比較重要的因素&#xff0c;因此對價格因素分析&#x…

Langchain中的表格解析:RAG 和表格的愛恨情仇

實現 RAG(Retrieval-Augmented Generation)是一個挑戰,尤其是在有效解析和理解非結構化文檔中的表格時。這在處理掃描文檔或圖像格式的文檔時尤為困難。這些挑戰至少包括以下三個方面: 1.表格的“叛逆期”:不準確的解析可能會破壞表格結構: 表格在文檔里就像個叛逆的青少…

Solr-搜索引擎-入門到精通

以下是對 Apache Solr 的簡介及其常用語法的快速入門指南&#xff1a; 一、Solr 是什么&#xff1f; ? 核心定位&#xff1a;Apache Solr 是一個基于 Lucene 的高性能、開源的搜索平臺&#xff0c;支持全文檢索、分詞、高亮、聚合統計等功能。 ? 核心功能&#xff1a; ? 全…

原生后臺GPS位置限制,降低功耗

1.后臺 GPS 位置限制的背景 為了控制功耗&#xff0c;Android 平臺對后臺應用獲取位置信息的頻率進行了限制。后臺的定義與后臺執行限制一致&#xff0c;即應用不在前臺運行時被視為后臺應用。 2.更新間隔限制&#xff1a; 后臺應用獲取位置信息的更新間隔不能超過一定閾值。…

Docker 搭建 PlantUML 服務:高效生成 UML 圖的最佳實踐

PlantUML 是一款開源的 UML 圖形生成工具&#xff0c;它支持生成類圖、時序圖、用例圖、活動圖等多種類型的 UML 圖&#xff0c;廣泛應用于軟件設計、文檔編寫以及團隊溝通中。通過 Docker 安裝 PlantUML&#xff0c;開發者可以快速搭建環境&#xff0c;輕松生成 UML 圖&#x…

簡鹿辦公匯總快速打開 Windows 資源管理器的幾種方式

無論你是剛開始使用電腦的新手&#xff0c;還是已經有一定經驗的用戶&#xff0c;了解如何在 Windows 系統中打開資源管理器都是一個非常基本且重要的技能。Windows 資源管理器&#xff08;現在稱為“文件資源管理器”&#xff09;是幫助你瀏覽、查找和管理計算機上所有文件的主…