精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

字節(jié)跳動C++二面:手寫shared_ptr實(shí)現(xiàn)

開發(fā) 前端
在字節(jié)跳動 C++ 二面中,要求手寫shared_ptr實(shí)現(xiàn),這一題目旨在深度考察面試者對 C++ 內(nèi)存管理、對象生命周期把控、模板編程以及運(yùn)算符重載等多方面核心知識的理解與運(yùn)用能力。

在 C++ 開發(fā)領(lǐng)域,智能指針是一項(xiàng)極為重要的機(jī)制,它極大地提升了內(nèi)存管理的安全性與便捷性。其中,shared_ptr作為智能指針家族的關(guān)鍵成員,采用引用計數(shù)的方式,允許多個指針共享同一對象的所有權(quán),當(dāng)最后一個指向?qū)ο蟮膕hared_ptr被銷毀時,對象所占用的內(nèi)存會被自動釋放,有效規(guī)避了內(nèi)存泄漏的風(fēng)險。

在字節(jié)跳動 C++ 二面中,要求手寫shared_ptr實(shí)現(xiàn),這一題目旨在深度考察面試者對 C++ 內(nèi)存管理、對象生命周期把控、模板編程以及運(yùn)算符重載等多方面核心知識的理解與運(yùn)用能力。要想成功完成這一挑戰(zhàn),面試者不僅需要清晰掌握shared_ptr的底層運(yùn)行原理,還得能夠用嚴(yán)謹(jǐn)、高效且符合 C++ 最佳實(shí)踐的代碼將其準(zhǔn)確呈現(xiàn)出來。接下來,我們就一同深入剖析如何逐步實(shí)現(xiàn)一個簡易版的shared_ptr 。

Part1.什么是shared_ptr?

在 C++ 編程的世界中,內(nèi)存管理一直是一個讓人又愛又恨的話題。手動管理內(nèi)存就像是在走鋼絲,稍有不慎就會引發(fā)內(nèi)存泄漏、懸空指針等一系列嚴(yán)重的問題,讓程序變得脆弱不堪。為了解決這些棘手的問題,C++11 引入了智能指針這個強(qiáng)大的工具,而std::shared_ptr就是其中的佼佼者。

std:shared_ptr是 C++ 標(biāo)準(zhǔn)庫提供的一種智能指針,它采用了引用計數(shù)的機(jī)制,允許多個指針共享同一個對象的所有權(quán) ,這就好比多個小伙伴共同擁有一個玩具,每個人都對這個玩具有一定的使用權(quán)。當(dāng)最后一個擁有這個玩具的小伙伴不再需要它時(即引用計數(shù)為 0),玩具就會被自動回收,這樣就避免了手動管理內(nèi)存時可能出現(xiàn)的各種麻煩。

例如,在一個圖形渲染引擎中,有多個模塊可能需要訪問同一個紋理資源。使用std::shared_ptr,可以讓這些模塊共享對紋理資源的引用,而不必?fù)?dān)心資源的釋放問題。當(dāng)所有模塊都不再使用該紋理時,std::shared_ptr會自動釋放紋理占用的內(nèi)存,大大提高了內(nèi)存管理的安全性和效率。

在實(shí)際使用中,std::shared_ptr的操作非常靈活。比如,我們可以通過std::make_shared函數(shù)來創(chuàng)建一個std::shared_ptr對象,這種方式不僅更加簡潔,而且效率更高,因?yàn)樗淮涡苑峙淞藢ο蠛鸵糜嫈?shù)所需的內(nèi)存。同時,std::shared_ptr還支持賦值、比較等操作,使得代碼的編寫更加自然和直觀。

1.1 產(chǎn)生的原因

shared_ptr的產(chǎn)生與unique_ptr類似,都是為了解決raw pointer的new和delete的成對使用,導(dǎo)致的野指針、內(nèi)存泄漏、重復(fù)釋放內(nèi)存等。

不過shared_ptr與unique_ptr場景又有所不同,這里主要是一個raw pointer在不同的代碼塊之間傳來傳去的場景,或者指針指向的內(nèi)存比較大,這段內(nèi)存可以切分成很多小部分,但是他們卻需要共享彼此的數(shù)據(jù)。

1.2 shared_ptr特性

shared_ptr 有兩個特性:

  • 特性1: 對raw pointer進(jìn)行了一層封裝,讓C++程序員不用再擔(dān)心何時去釋放分配好的內(nèi)存。
  • 特性2: 共享,使用shared_ptr的指針可以共享同一塊內(nèi)存中的數(shù)據(jù)。

思想是:該類型智能指針在實(shí)現(xiàn)上采用的是引用計數(shù)機(jī)制,即便有一個 shared_ptr 指針放棄了堆內(nèi)存的“使用權(quán)”(引用計數(shù)減 1),也不會影響其他指向同一堆內(nèi)存的 shared_ptr 指針(只有引用計數(shù)為 0 時,堆內(nèi)存才會被自動釋放)。

1.3 shared_ptr的優(yōu)勢

(1)自動釋放:當(dāng)最后一個std::shared_ptr離開作用域時,引用計數(shù)變?yōu)榱悖鼤詣诱{(diào)用對象的析構(gòu)函數(shù),防止內(nèi)存泄漏 。在一個網(wǎng)絡(luò)通信模塊中,我們可能會創(chuàng)建一個std::shared_ptr來管理一個連接對象。當(dāng)所有與該連接相關(guān)的操作完成,并且指向該連接對象的std::shared_ptr都超出作用域時,連接對象會被自動釋放,無需手動調(diào)用析構(gòu)函數(shù)。這樣一來,我們就不用擔(dān)心因?yàn)槭韬龆鴮?dǎo)致連接資源沒有被正確釋放,從而大大提高了代碼的可靠性。

#include <iostream>
#include <memory>

// 模擬網(wǎng)絡(luò)連接對象
class Connection {
public:
    Connection() { std::cout << "Connection established\n"; }
    ~Connection() { std::cout << "Connection released\n"; }

    void send(const std::string& data) {
        std::cout << "Sending data: " << data << "\n";
    }
};

// 模擬網(wǎng)絡(luò)通信模塊
void handleConnection() {
    // 創(chuàng)建 shared_ptr 管理連接對象(引用計數(shù)=1)
    auto conn = std::make_shared<Connection>();

    // 模擬多個操作共享該連接
    auto task1 = [conn]() { conn->send("Task1 data"); };
    auto task2 = [conn]() { conn->send("Task2 data"); }; // 引用計數(shù)增加到3

    task1();
    task2();

    // task1/task2的lambda析構(gòu),引用計數(shù)減回1
} // conn離開作用域,引用計數(shù)歸零,自動調(diào)用Connection析構(gòu)

int main() {
    handleConnection();

    // 輸出示例:
    // Connection established
    // Sending data: Task1 data
    // Sending data: Task2 data
    // Connection released

    return 0;
}

(2)對象共享:多個std::shared_ptr可以指向同一對象,這使得資源共享的實(shí)現(xiàn)變得更加簡單。在一個游戲開發(fā)項(xiàng)目中,多個游戲?qū)ο罂赡苄枰蚕硗粋€紋理資源。通過std::shared_ptr,我們可以輕松地讓這些游戲?qū)ο蠊蚕韺y理的引用,而不必為每個對象單獨(dú)復(fù)制紋理數(shù)據(jù),節(jié)省了內(nèi)存空間,同時也提高了資源的利用率。

#include <iostream>
#include <memory>
#include <vector>

// 模擬紋理資源類
class Texture {
public:
    Texture(const std::string& path) : m_path(path) {
        std::cout << "Loaded texture: " << m_path << "\n";
    }
    ~Texture() { std::cout << "Unloaded texture: " << m_path << "\n"; }

    void render(int x, int y) const {
        std::cout << "Rendering texture at (" << x << ", " << y 
                  << ") from: " << m_path << "\n";
    }

private:
    std::string m_path;
};

// 游戲?qū)ο蠡悾ㄊ褂霉蚕砑y理)
class GameObject {
public:
    GameObject(std::shared_ptr<Texture> texture) : m_texture(texture) {}

    virtual void draw() = 0;

protected:
    std::shared_ptr<Texture> m_texture; // 共享紋理的智能指針
};

// 具體游戲?qū)ο螅航巧?class Character : public GameObject {
public:
    using GameObject::GameObject;

    void draw() override {
        m_texture->render(100, 200); // 使用共享紋理
        std::cout << "Character drawn\n";
    }
};

// 具體游戲?qū)ο螅簣鼍氨尘?class Background : public GameObject {
public:
    using GameObject::GameObject;

    void draw() override {
        m_texture->render(0, 0); // 使用同一份紋理(可能縮放或裁剪)
        std::cout << "Background drawn\n";
    }
};

int main() {
    // 1. 加載紋理(僅一次)
    auto sharedTexture = std::make_shared<Texture>("assets/hero.png");

    // 2. 創(chuàng)建多個共享該紋理的游戲?qū)ο?    Character hero(sharedTexture);
    Background scene(sharedTexture);

    // 3. 渲染時無需關(guān)心紋理生命周期
    hero.draw();
    scene.draw();

    // 4. main結(jié)束時,所有對象析構(gòu)后引用計數(shù)歸零,自動釋放紋理

   return 0;
}

3)異常安全:std::shared_ptr的引用計數(shù)會自動管理,不會因?yàn)楹瘮?shù)異常退出而泄漏內(nèi)存。在進(jìn)行復(fù)雜的數(shù)據(jù)庫操作時,可能會涉及多個步驟,其中任何一步都有可能拋出異常。如果我們使用std::shared_ptr來管理數(shù)據(jù)庫連接對象,即使在操作過程中發(fā)生異常,std::shared_ptr也會確保連接對象被正確釋放,避免了內(nèi)存泄漏和資源懸空的問題,保證了程序的健壯性。

#include <iostream>
#include <memory>
#include <stdexcept>

// 模擬數(shù)據(jù)庫連接類
class DatabaseConnection {
public:
    DatabaseConnection(const std::string& url) : m_url(url) {
        std::cout << "Connected to database: " << m_url << "\n";
    }

    ~DatabaseConnection() {
        std::cout << "Disconnected from database: " << m_url << "\n";
    }

    void executeQuery(const std::string& sql) {
        if (sql.empty()) throw std::runtime_error("Empty SQL query");
        std::cout << "Executed: " << sql << "\n";
    }

private:
    std::string m_url;
};

// 高風(fēng)險操作:可能拋出異常的復(fù)雜數(shù)據(jù)庫事務(wù)
void riskyDatabaseOperation(std::shared_ptr<DatabaseConnection> conn) {
    conn->executeQuery("BEGIN TRANSACTION");  // 步驟1:開始事務(wù)

    // 模擬可能失敗的操作(如違反約束)
    conn->executeQuery("UPDATE users SET balance = -100 WHERE id = 123"); // 步驟2:可能拋異常

    conn->executeQuery("COMMIT");             // 步驟3:提交事務(wù)(若異常則不會執(zhí)行)
}

int main() {
    try {
        // 1. 創(chuàng)建共享的數(shù)據(jù)庫連接
        auto dbConn = std::make_shared<DatabaseConnection>("mysql://localhost:3306");

        // 2. 執(zhí)行高風(fēng)險操作(即使內(nèi)部拋出異常,conn也會被釋放)
        riskyDatabaseOperation(dbConn);

    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << "\n";

        // 無需手動釋放dbConn!shared_ptr會在棧展開時自動析構(gòu)
    }

   return 0;
}

Part2.shared_ptr的使用方法

2.1 創(chuàng)建 shared_ptr 對象

在 C++ 中,創(chuàng)建std::shared_ptr對象主要有兩種常見方式。一種是使用std::make_shared函數(shù) ,它能一次性分配對象和控制塊的內(nèi)存,效率較高,語法也更為簡潔。比如創(chuàng)建一個指向int類型對象的std::shared_ptr,可以這樣寫:

auto ptr1 = std::make_shared<int>(42);

這就創(chuàng)建了一個std::shared_ptr,它指向一個值為 42 的int對象。

另一種方式是使用原始指針來構(gòu)造std::shared_ptr,但這種方式需要注意原始指針必須是通過new分配的,否則會導(dǎo)致未定義行為 。示例如下:

int* rawPtr = new int(10);
std::shared_ptr<int> ptr2(rawPtr);

這里先創(chuàng)建了一個原始指針rawPtr,然后用它構(gòu)造了std::shared_ptr對象ptr2。不過這種方式相對繁瑣,且容易出錯,因?yàn)樾枰謩庸芾碓贾羔樀纳芷冢愿扑]使用std::make_shared。

2.2 引用計數(shù)相關(guān)操作

std::shared_ptr的核心特性之一就是引用計數(shù),通過一些成員函數(shù),我們可以對引用計數(shù)進(jìn)行操作和查詢。use_count函數(shù)用于返回當(dāng)前有多少個std::shared_ptr指向同一個對象,主要用于調(diào)試目的 。例如:

auto ptr3 = std::make_shared<int>(100);
std::cout << "ptr3的引用計數(shù): " << ptr3.use_count() << std::endl; 
auto ptr4 = ptr3;
std::cout << "賦值后ptr3的引用計數(shù): " << ptr3.use_count() << std::endl;

在上述代碼中,首先創(chuàng)建ptr3時,其引用計數(shù)為 1;當(dāng)把ptr3賦值給ptr4后,它們指向同一個對象,引用計數(shù)變?yōu)?2。

unique函數(shù)則用于判斷當(dāng)前std::shared_ptr是否是指向?qū)ο蟮奈ㄒ恢羔?,如果是則返回true,否則返回false。接著上面的代碼:

if (ptr3.unique()) {
    std::cout << "ptr3是唯一指向?qū)ο蟮闹羔? << std::endl;
} else {
    std::cout << "ptr3不是唯一指向?qū)ο蟮闹羔? << std::endl;
}

由于ptr3和ptr4共享對象,所以ptr3.unique()會返回false。

reset函數(shù)用于重置std::shared_ptr,它有兩種常見用法。不帶參數(shù)調(diào)用reset時,會減少引用計數(shù),如果引用計數(shù)變?yōu)?0,就會釋放所指向的對象,并將當(dāng)前std::shared_ptr置為空 。例如:

ptr3.reset();
std::cout << "reset后ptr3的引用計數(shù): " << ptr3.use_count() << std::endl;

此時ptr3的引用計數(shù)變?yōu)?0(如果沒有其他指向該對象的std::shared_ptr),對象被釋放,ptr3變?yōu)榭罩羔槨?/span>

帶參數(shù)調(diào)用reset時,會先減少原對象的引用計數(shù),然后讓std::shared_ptr指向新的對象 。例如:

ptr4.reset(new int(200));
std::cout << "ptr4指向新對象后的引用計數(shù): " << ptr4.use_count() << std::endl;

這里ptr4先減少對原對象的引用計數(shù),然后指向一個新的值為 200 的int對象,引用計數(shù)變?yōu)?1。

2.3 作為普通指針使用

std::shared_ptr重載了*和->操作符,這使得它可以像普通指針一樣使用 。通過*操作符可以解引用std::shared_ptr,訪問其所指向的對象的值。例如:

auto ptr5 = std::make_shared<int>(50);
int value = *ptr5;
std::cout << "ptr5指向的值: " << value << std::endl;

這里通過*ptr5獲取到ptr5指向的int對象的值,并賦值給value。

而->操作符則用于訪問所指向?qū)ο蟮某蓡T函數(shù)或成員變量。假設(shè)有一個自定義類MyClass:

class MyClass {
public:
    void print() {
        std::cout << "這是MyClass的成員函數(shù)" << std::endl;
    }
};
auto ptr6 = std::make_shared<MyClass>();
ptr6->print();

在這段代碼中,通過ptr6->print()調(diào)用了MyClass對象的print成員函數(shù),就如同使用普通指針一樣方便 。這種重載操作符的設(shè)計,使得std::shared_ptr在使用上更加直觀和自然,無需額外的函數(shù)調(diào)用就能完成對對象的操作。

Part3.循環(huán)引用問題及解決

3.1 循環(huán)引用示例

雖然std::shared_ptr在內(nèi)存管理方面表現(xiàn)出色,但在使用過程中,如果不注意其引用計數(shù)機(jī)制,就可能會遇到循環(huán)引用的問題 。循環(huán)引用是指兩個或多個對象相互引用對方的std::shared_ptr,從而導(dǎo)致引用計數(shù)永遠(yuǎn)無法歸零,最終造成內(nèi)存泄漏。

下面是一個具體的代碼示例,展示了循環(huán)引用是如何發(fā)生的:

#include <iostream>
#include <memory>

class B;

class A {
public:
    std::shared_ptr<B> b_ptr;
    ~A() {
        std::cout << "A destroyed" << std::endl;
    }
};

class B {
public:
    std::shared_ptr<A> a_ptr;
    ~B() {
        std::cout << "B destroyed" << std::endl;
    }
};

int main() {
    auto a = std::make_shared<A>();
    auto b = std::make_shared<B>();

    a->b_ptr = b;
    b->a_ptr = a;

    return 0;
}

在上述代碼中,A類和B類相互持有對方的std::shared_ptr。當(dāng)main函數(shù)結(jié)束時,a和b的局部變量被銷毀,它們的引用計數(shù)會減 1,但由于a的b_ptr指向b,b的a_ptr指向a,所以a和b的引用計數(shù)始終無法降為 0 ,導(dǎo)致A和B的析構(gòu)函數(shù)都不會被調(diào)用,內(nèi)存無法釋放,從而發(fā)生內(nèi)存泄漏。這種循環(huán)引用的問題在實(shí)際項(xiàng)目中可能很難被發(fā)現(xiàn),尤其是在復(fù)雜的對象關(guān)系中,它會逐漸消耗系統(tǒng)資源,影響程序的性能和穩(wěn)定性 。

3.2 使用 std::weak_ptr 打破循環(huán)引用

為了解決std::shared_ptr的循環(huán)引用問題,C++ 引入了std::weak_ptr 。std::weak_ptr是一種弱引用智能指針,它不擁有所指向?qū)ο蟮乃袡?quán),不會增加對象的引用計數(shù),主要用于解決std::shared_ptr循環(huán)引用的問題,同時提供一種安全的方式來訪問std::shared_ptr所管理的對象 。

std::weak_ptr的核心特性之一是它的lock方法,該方法用于嘗試獲取一個指向所引用對象的std::shared_ptr 。如果對象已經(jīng)被釋放,lock方法會返回一個空的std::shared_ptr,通過這種方式可以安全地檢查對象是否仍然有效,避免懸空指針的問題。

下面是使用std::weak_ptr解決上述循環(huán)引用問題的代碼示例:

#include <iostream>
#include <memory>

class B;

class A {
public:
    std::shared_ptr<B> b_ptr;
    ~A() {
        std::cout << "A destroyed" << std::endl;
    }
};

class B {
public:
    std::weak_ptr<A> a_weak;
    ~B() {
        std::cout << "B destroyed" << std::endl;
    }
};

int main() {
    auto a = std::make_shared<A>();
    auto b = std::make_shared<B>();

    a->b_ptr = b;
    b->a_weak = a;

    return 0;
}

在這個改進(jìn)后的代碼中,B類不再持有A類的std::shared_ptr,而是使用std::weak_ptr來引用A 。當(dāng)main函數(shù)結(jié)束時,a的引用計數(shù)會因?yàn)榫植孔兞縜的銷毀而減為 0,A對象被正確釋放;接著,b的引用計數(shù)也會減為 0,B對象也被釋放,從而避免了循環(huán)引用導(dǎo)致的內(nèi)存泄漏問題 。

當(dāng)需要通過std::weak_ptr訪問對象時,可以使用lock方法,例如:

class B {
public:
    std::weak_ptr<A> a_weak;
    void accessA() {
        auto temp = a_weak.lock();
        if (temp) {
            // 安全地訪問A對象
            temp->someFunction(); 
        } else {
            std::cout << "A對象已被釋放" << std::endl;
        }
    }
    ~B() {
        std::cout << "B destroyed" << std::endl;
    }
};

在上述代碼的accessA方法中,先通過lock方法獲取A對象的std::shared_ptr,并檢查其是否為空 。如果不為空,就可以安全地訪問A對象的成員;如果為空,說明A對象已經(jīng)被釋放,避免了懸空指針的風(fēng)險。

Part4.shared_ptr的線程安全性

4.1 引用計數(shù)的線程安全

在多線程環(huán)境下,std::shared_ptr的引用計數(shù)操作是線程安全的,這是它的一個重要特性 。當(dāng)多個線程同時對同一個std::shared_ptr進(jìn)行復(fù)制、賦值或銷毀等操作時,其引用計數(shù)的遞增和遞減是通過原子操作來實(shí)現(xiàn)的,無需額外的加鎖機(jī)制 。這就好比有一個公共的計數(shù)器,多個線程可以同時對它進(jìn)行增加或減少操作,而且不會出現(xiàn)計數(shù)錯誤的情況。

例如,在一個多線程的文件處理系統(tǒng)中,多個線程可能同時讀取或處理同一個文件對象,每個線程都持有一個std::shared_ptr指向該文件對象 。當(dāng)某個線程完成對文件的處理,其持有的std::shared_ptr離開作用域時,引用計數(shù)會自動減 1,這個過程是線程安全的,不會因?yàn)槎嗑€程并發(fā)操作而導(dǎo)致引用計數(shù)錯誤,從而保證了文件對象在所有線程都不再需要時能被正確釋放 。這種原子操作的實(shí)現(xiàn),使得std::shared_ptr在多線程環(huán)境下的引用計數(shù)管理變得高效且可靠,大大降低了因多線程操作導(dǎo)致的內(nèi)存管理錯誤風(fēng)險 。

4.2 訪問對象的線程安全

雖然std::shared_ptr的引用計數(shù)是線程安全的,但對其指向?qū)ο蟮脑L問卻并非如此 。當(dāng)多個線程同時通過std::shared_ptr訪問和修改同一個對象時,如果沒有適當(dāng)?shù)耐酱胧涂赡軙l(fā)數(shù)據(jù)競爭和未定義行為 。例如,在一個多線程的銀行賬戶管理系統(tǒng)中,多個線程可能同時對同一個賬戶對象進(jìn)行取款和存款操作 。如果直接通過std::shared_ptr訪問賬戶對象,而不進(jìn)行任何同步控制,就可能出現(xiàn)數(shù)據(jù)不一致的情況,比如一個線程讀取了賬戶余額后,還未進(jìn)行更新操作,另一個線程又讀取了相同的余額并進(jìn)行操作,最終導(dǎo)致賬戶余額計算錯誤 。

為了保證對std::shared_ptr指向?qū)ο蟮陌踩L問,通常需要使用諸如std::mutex(互斥鎖)、std::lock_guard(RAII 風(fēng)格的鎖管理類)等同步機(jī)制 。下面是一個使用std::mutex來保護(hù)共享對象訪問的代碼示例:

#include <iostream>
#include <memory>
#include <mutex>
#include <thread>

class Counter {
public:
    Counter() : value(0) {}
    void increment() {
        std::lock_guard<std::mutex> lock(mtx);
        ++value;
    }
    int get() {
        std::lock_guard<std::mutex> lock(mtx);
        return value;
    }
private:
    int value;
    std::mutex mtx;
};

int main() {
    auto counter = std::make_shared<Counter>();
    std::thread threads[10];
    for (int i = 0; i < 10; ++i) {
        threads[i] = std::thread([counter]() {
            for (int j = 0; j < 100; ++j) {
                counter->increment();
            }
        });
    }
    for (auto& th : threads) {
        th.join();
    }
    std::cout << "Final counter value: " << counter->get() << std::endl; 
    return 0;
}

在上述代碼中,Counter類包含一個std::mutex成員變量mtx,用于保護(hù)對value成員變量的訪問 。在increment和get成員函數(shù)中,使用std::lock_guard<std::mutex>來自動管理鎖的生命周期,在進(jìn)入函數(shù)時自動加鎖,離開函數(shù)時自動解鎖 。這樣,當(dāng)多個線程同時調(diào)用increment函數(shù)時,通過鎖機(jī)制保證了每次只有一個線程能夠修改value,從而避免了數(shù)據(jù)競爭,確保了線程安全 。

注意事項(xiàng):雖然std::shared_ptr確保了引用計數(shù)的線程安全,但對對象本身的訪問并非線程安全。如果多個線程要修改std::shared_ptr指向的對象,仍然需要額外的同步措施(如使用std::mutex)來保證線程安全。

4.3 多線程修改 std::shared_ptr 指向的對象

如果多個線程需要同時訪問并修改 std::shared_ptr 指向的對象,使用 std::mutex 可以保證線程安全。這里提供一個示例展示如何使用 std::mutex 來保護(hù)對共享對象的訪問和修改。

我們創(chuàng)建一個共享的計數(shù)器對象,多個線程將同時訪問并修改該計數(shù)器。在沒有 std::mutex 保護(hù)的情況下,計數(shù)器的值可能會因數(shù)據(jù)競爭而出現(xiàn)錯誤。通過在訪問和修改計數(shù)器的代碼塊中添加互斥鎖,我們可以確保每個線程按順序訪問該資源,避免數(shù)據(jù)競爭。

#include <iostream>
#include <memory>
#include <thread>
#include <mutex>
#include <vector>

class Counter {
public:
    int value;

    Counter() : value(0) {}
    void increment() {
        ++value;
    }
    int getValue() const {
        return value;
    }
};

void thread_func(std::shared_ptr<Counter> counter, std::mutex& mtx) {
    for (int i = 0; i < 100; ++i) {
        std::lock_guard<std::mutex> lock(mtx);  // 加鎖保護(hù)對 counter 的訪問
        counter->increment();
    }
}

int main() {
    auto counter = std::make_shared<Counter>();
    std::mutex mtx;

    std::vector<std::thread> threads;

    // 啟動10個線程,每個線程對 counter 執(zhí)行 100 次 increment 操作
    for (int i = 0; i < 10; ++i) {
        threads.emplace_back(thread_func, counter, std::ref(mtx));
    }

    // 等待所有線程完成
    for (auto& t : threads) {
        t.join();
    }

    std::cout << "Final counter value: " << counter->getValue() << std::endl; // 期望輸出 1000

    return 0;
}

在這個例子中,Counter 類的對象由 std::shared_ptr 管理,并在多個線程中共享,在 thread_func 函數(shù)中,每次調(diào)用 counter->increment() 前,都用 std::lock_guard<std::mutex> 鎖定 mtx,保證每次訪問 increment() 是原子操作,std::lock_guard 是 RAII 風(fēng)格的鎖管理器,它會在代碼塊結(jié)束時自動釋放鎖。啟動 10 個線程,每個線程對共享計數(shù)器執(zhí)行 100 次增量操作。通過 std::mutex,我們保證了計數(shù)器的修改是線程安全的。

程序輸出:Final counter value: 1000;在沒有互斥鎖的情況下,counter->increment() 在多個線程中可能會發(fā)生競爭,導(dǎo)致最終計數(shù)值低于預(yù)期的 1000。使用 std::mutex 來保護(hù)對共享資源的訪問,保證了線程安全,確保最終計數(shù)器值為 1000。

責(zé)任編輯:武曉燕 來源: 深度Linux
相關(guān)推薦

2025-05-28 08:50:00

C++循環(huán)引用節(jié)點(diǎn)

2025-05-22 10:10:00

C++循環(huán)引用開發(fā)

2025-06-24 10:00:00

智能指針代碼unique_ptr

2025-02-26 01:23:02

C++11Raw代碼

2022-04-07 16:35:59

PGO 優(yōu)化profile 數(shù)據(jù)編譯優(yōu)化

2025-09-15 02:00:00

2025-04-08 09:20:00

Sentinel限流微服務(wù)

2025-08-18 02:11:00

2022-10-10 08:13:16

遞歸通用代碼

2025-08-12 02:55:00

2025-10-09 01:15:00

2025-09-15 02:00:00

2025-09-11 01:55:00

2025-08-12 01:22:00

2023-11-17 11:48:08

智能指針C++

2024-09-25 15:57:56

2021-06-30 17:38:03

Trie 樹字符Java

2025-03-28 10:47:05

開發(fā)注解Java

2024-08-30 08:59:15

2021-03-01 11:53:15

面試偽共享CPU
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

精品国产亚洲AV| 久草视频免费在线播放| 成人亚洲视频| 亚洲综合激情网| 免费99视频| 国产又粗又猛又爽又黄的视频一| 国精品一区二区| 国产香蕉精品视频一区二区三区| 91av免费观看| 日韩av超清在线观看| 亚洲靠逼com| 欧美一区二区视频在线| www.国产.com| 麻豆精品视频在线观看视频| 午夜免费在线观看精品视频| 91免费在线看片| 久久久精品国产**网站| 欧美另类变人与禽xxxxx| 少妇高潮毛片色欲ava片| 日本天堂在线观看| 91丝袜高跟美女视频| 亚洲最大av网| 中国精品一区二区| 午夜宅男久久久| 九九热这里只有精品6| 超薄肉色丝袜一二三| 国产精品超碰| 日韩三级av在线播放| 另类小说色综合| 成人美女大片| 无吗不卡中文字幕| 国产高清不卡无码视频| 欧洲不卡av| 国产欧美日韩在线看| 精品久久久久久一区| 黄色一级大片在线免费看国产| 美美哒免费高清在线观看视频一区二区| 国内外成人免费激情在线视频网站| 亚洲色图日韩精品| 国产一区二区三区不卡视频网站| 亚洲第一男人天堂| aaa黄色大片| 成人直播在线观看| 精品国产91洋老外米糕| 亚洲性图第一页| 成人97精品毛片免费看| 欧美精品第一页| 不卡中文字幕在线观看| 国产成+人+综合+亚洲欧美| 色欧美日韩亚洲| 激情视频综合网| 欧美三级精品| 欧美亚洲愉拍一区二区| 日本在线一二三区| 久久av影院| 欧美丰满美乳xxx高潮www| jizz18女人| 亚洲精品一区av| 日韩欧美中文字幕精品| 在线观看欧美一区二区| 澳门精品久久国产| 日韩激情av在线免费观看| 亚洲国产果冻传媒av在线观看| 国产精品久久久久久久久久白浆 | 精品一区91| 3atv一区二区三区| 性感美女一区二区三区| 波多野结衣一区二区三区免费视频| 亚洲а∨天堂久久精品喷水 | 91成人噜噜噜在线播放| 精品成人一区二区| www.色天使| 成人女性视频| 九九精品视频在线| 国产手机在线视频| 日韩精品一区第一页| 国产一区玩具在线观看| 99久久精品国产色欲| 大白屁股一区二区视频| 久久亚洲高清| 久久bbxx| 欧美日韩国产在线看| 日本新janpanese乱熟| 亚洲男男av| 亚洲激情国产精品| 999精品久久久| 国内揄拍国内精品久久| 奇米一区二区三区四区久久| 又污又黄的网站| 国产精品456| 久久精品第九区免费观看| 国产乱理伦片a级在线观看| 亚洲欧美乱综合| 91好吊色国产欧美日韩在线| 韩国三级一区| 精品福利一区二区三区 | 日韩美女视频一区| 搞av.com| 欧美亚洲人成在线| 亚洲国产日韩欧美在线动漫| 亚洲自拍偷拍图| 狠狠色丁香久久综合频道| 日韩av电影手机在线观看| av网站免费大全| 欧美国产禁国产网站cc| 福利视频免费在线观看| se69色成人网wwwsex| 亚洲成av人片在线观看香蕉| 久久精品色妇熟妇丰满人妻| 亚洲免费高清| 91亚洲精品久久久| 国产精品毛片一区二区三区四区| 亚洲精选一二三| 国产又大又黄又粗又爽| 天天躁日日躁狠狠躁欧美| 欧美超级乱淫片喷水| 久草热在线观看| 91亚洲午夜精品久久久久久| a级片一区二区| 精品亚洲a∨| 亚洲欧美中文字幕在线一区| 国产精品成人aaaa在线| 黑人巨大精品欧美黑白配亚洲| 蜜桃视频在线观看成人| а√天堂中文在线资源8| 69久久99精品久久久久婷婷| 亚洲色图 激情小说| 亚洲影院在线| 国产一区二区三区奇米久涩 | 欧美一二区在线观看| 欧美在线播放视频| 免费国产精品视频| 亚洲一二三四久久| 欧美一级大片免费看| 希岛爱理一区二区三区| 国产精品男人的天堂| 免费在线视频一级不卡| 天天综合网天天综合色| 国产精品偷伦视频免费观看了| 亚洲国产一区二区三区在线播放| 国产精品一区二区三区久久久 | 97caocao| 亚洲免费观看在线观看| 色呦色呦色精品| 五月久久久综合一区二区小说| 国产精品欧美一区二区三区奶水| 九色在线免费| 色系网站成人免费| 一区二区三区伦理片| 日韩国产欧美在线观看| 亚洲高清资源综合久久精品| 黄色精品视频网站| 中文字幕无线精品亚洲乱码一区 | 国产自产自拍视频在线观看| 亚洲国内精品在线| 国产精品500部| 97se亚洲国产综合自在线观| 国产97在线 | 亚洲| 日本久久成人网| 日本高清久久天堂| 日韩精品毛片| 日韩精品中文字幕一区| 国产成人无码精品| 久久理论电影网| 一道本视频在线观看| 亚洲第一偷拍| 国产精品日韩一区二区三区| 欧美freesex| 在线性视频日韩欧美| 国产绿帽一区二区三区| 一区二区欧美视频| 久久国产精品无码一级毛片| 青青草国产成人99久久| 中文字幕不卡每日更新1区2区| 欧美日韩一区二区三区在线| 男人天堂999| 欧美一区二区三| 91久久夜色精品国产网站| 污污的视频在线观看| 亚洲国产免费av| 久久久精品毛片| 亚洲人成精品久久久久| 婷婷五月精品中文字幕| 久久狠狠一本精品综合网| 一本一本久久a久久精品综合妖精| 电影一区二区三区久久免费观看| 久久久人成影片一区二区三区观看| 无码h黄肉3d动漫在线观看| 91福利在线播放| 久久久91视频| 国产婷婷精品av在线| www.色.com| 久久av一区| 青青草原网站在线观看| 天天久久夜夜| av一区二区在线看| 国产综合av| 欧美精品www在线观看| 粉嫩av一区| 亚洲福利在线播放| 国产巨乳在线观看| 日本电影亚洲天堂一区| 欧美久久久久久久久久久久| 国产亚洲欧美色| 中文在线观看免费视频| 精品一区二区三区日韩| 97超碰青青草| 亚洲国内自拍| 三级在线免费观看| 欧美偷拍综合| 欧美动漫一区二区| baoyu135国产精品免费| 国产女同一区二区| 手机看片久久| 97在线看免费观看视频在线观看| 国产区在线看| 国产一区二区三区视频免费| 日本黄色免费视频| 日韩无一区二区| 夜夜狠狠擅视频| 日本乱人伦一区| 国产在线观看黄色| 亚洲成人av中文| 欧美极品aaaaabbbbb| 亚洲视频一二三| 久久久久久久毛片| 26uuu精品一区二区三区四区在线| 国产精品一级无码| 国产精品资源在线看| 亚洲免费成人在线视频| 人禽交欧美网站| 妞干网在线免费视频| 中文精品在线| 国产h视频在线播放| 黄色工厂这里只有精品| 国产免费裸体视频| 欧美日韩国产色综合一二三四| 在线丝袜欧美日韩制服| 日韩在线观看| 中文字幕欧美人与畜| 色综合狠狠操| 国产精品av免费| 99精品一区| 亚洲黄色网址在线观看| 欧美成人一区二免费视频软件| 做爰高潮hd色即是空| 亚洲成人三区| 97超碰国产精品| 亚洲大胆在线| 国产最新免费视频| 久久精品女人| 999精品视频在线| 美国一区二区三区在线播放| 国内外成人免费在线视频| 另类中文字幕网| 欧美激情第一区| 懂色av一区二区夜夜嗨| 手机在线成人av| 国产亚洲成年网址在线观看| www.日本高清视频| 国产精品传媒在线| 欧美性猛交xxxxx少妇| 亚洲宅男天堂在线观看无病毒| 国产一卡二卡在线| 色综合久久久久网| 一级片一区二区三区| 精品少妇一区二区三区在线视频| 日韩中文字幕免费观看| 精品视频在线播放| 国产在线三区| 久久久久999| 17videosex性欧美| 国产精品户外野外| 精品一区二区三区四区五区 | 欧美三级午夜理伦三级| 秋霞av亚洲一区二区三| 伊人色在线视频| aaa国产一区| 91制片厂在线| 亚洲成人一区在线| 国产99免费视频| 91精品国产乱| 日韩porn| 久久99国产精品自在自在app| 国产精品论坛| 成人黄色在线播放| 欧美理伦片在线播放| 一区二区av| 宅男噜噜噜66一区二区| 日本一二区免费| 99精品欧美一区二区蜜桃免费 | 又紧又大又爽精品一区二区| 日韩欧美激情视频| 欧美日韩免费视频| 女人18毛片一区二区三区| 在线看国产精品| 高清视频在线观看三级| 国产日韩中文字幕在线| 欧美日韩破处| www.-级毛片线天内射视视| 亚洲免费中文| 国产成人精品一区二区在线小狼| 久久精品日韩一区二区三区| 久久久久久久中文字幕| 欧美日韩亚洲综合| 色视频在线观看| 欧美人交a欧美精品| 福利精品一区| 蜜桃91精品入口| 国产精品啊啊啊| 久久婷五月综合| 91捆绑美女网站| 国产真人真事毛片| 3d成人动漫网站| 在线免费观看黄色| 国产精品美女av| 精品在线播放| 国产极品粉嫩福利姬萌白酱| 国产成人亚洲综合a∨婷婷| 天天爽天天爽天天爽| 欧美亚洲综合一区| 国产尤物视频在线| 91精品国产色综合久久不卡98| 亚洲1区在线观看| 日本a级片在线观看| 黑人精品欧美一区二区蜜桃| 国产一级淫片久久久片a级| 91久久国产综合久久| 青青草在线免费观看| 国产91精品视频在线观看| 国产精品sss在线观看av| www.亚洲成人网| 国产高清不卡一区二区| 国产探花在线播放| 日韩视频在线永久播放| 国产美女av在线| 国产在线高清精品| 99久久www免费| 黄色小视频免费网站| 国产精品青草久久| 亚洲怡红院av| 伦理中文字幕亚洲| 看亚洲a级一级毛片| 日韩精品第1页| 国产成人精品综合在线观看| 久久老司机精品视频| 精品国产青草久久久久福利| 欧美xxxx做受欧美88bbw| 99视频网站| 亚洲人成免费| www.色多多| 欧美日韩精品一区二区三区蜜桃| 91电影在线播放| 91免费在线视频网站| 重囗味另类老妇506070| 2025中文字幕| 婷婷开心激情综合| 国产在线观看高清视频| 国产精品久久久久久久久久免费| 日韩精品免费一区二区在线观看| 99热这里只有精品在线播放| 亚洲色图制服诱惑| 国产小视频一区| 日本亚洲欧洲色α| 日韩精品一区二区久久| 久久撸在线视频| 一区二区三区成人在线视频| 天天干天天爱天天操| 欧美综合国产精品久久丁香| 成人黄色av| wwwww在线观看| 一本久道久久综合中文字幕| 中文字幕日本在线观看| 99视频在线播放| 亚洲欧美成人| 午夜剧场免费在线观看| 亚洲白虎美女被爆操| 国产精品亚洲一区二区三区在线观看| 视频一区亚洲| 国产成人av电影免费在线观看| 日本少妇全体裸体洗澡| 在线看日韩av| 国产精伦一区二区三区| 九色91popny| 亚洲一区二区综合| 黄网在线免费| 91情侣在线视频| 视频一区在线播放| 欧美日韩在线观看成人| 亚洲天堂2020| 国产福利一区二区精品秒拍| 亚洲欧美久久久久| 午夜精品123| 麻豆传媒在线免费| 国内精品久久国产| 国产主播一区二区| 欧美黄色一级大片| 欧美激情女人20p| 国产韩日影视精品| 亚洲国产欧美视频|