精品欧美一区二区三区在线观看 _久久久久国色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ù)棧公眾號

性猛交xxxx| 色啦啦av综合| 成人影院免费观看| 国产一区欧美一区| 久久久久久尹人网香蕉| 亚洲人成人无码网www国产| 欧美男男gaygay1069| 亚洲综合一二区| 欧美日韩精品久久久免费观看| 在线观看毛片视频| 亚洲国产激情| 日韩中文字幕国产| 久久人人妻人人人人妻性色av| 国产精品久久久久久久久久齐齐 | 欧美成人国产精品一区二区| 在线观看亚洲精品福利片| 欧美日韩裸体免费视频| 国产高潮呻吟久久久| 天堂av在线资源| 国产一区二区精品久久99| 2025国产精品视频| 青青草激情视频| 精品一区二区三区在线| 精品国产露脸精彩对白| 中文字幕22页| 电影一区二区三区| 亚洲二区在线观看| 欧美 另类 交| 成年在线观看免费人视频| 成人av网在线| 2014亚洲精品| 中文字幕在线观看你懂的| 在线综合亚洲| 色综合男人天堂| 亚洲天堂网av在线| 欧美综合一区| 亚洲香蕉成人av网站在线观看 | 一级黄色片在线观看| 久久国产福利| 68精品久久久久久欧美| 久久综合激情网| 7777久久香蕉成人影院| 日韩在线免费av| av男人的天堂av| 亚洲综合影院| 日韩精品一区二区三区在线观看 | 91在线你懂的| 美女视频黄久久| 国产精品久久一区| 欧美男人天堂网| 日韩中文字幕区一区有砖一区 | 青草视频在线观看视频| 亚洲色图美国十次| 亚洲精品视频观看| 青青草免费在线视频观看| 精品视频在线一区二区| 最新国产精品久久精品| 国产精品88久久久久久妇女| 91在线不卡| 国产精品电影院| 宅男在线精品国产免费观看| 欧美午夜电影一区二区三区| 国产日韩高清在线| 亚洲在线观看一区| 九七久久人人| 亚洲一区在线电影| 日本xxxxxxxxxx75| 岛国在线视频网站| 色菇凉天天综合网| 波多结衣在线观看| 成人污污www网站免费丝瓜| 91精品国产综合久久精品| 久久人人爽人人片| 成人香蕉社区| 亚洲精品资源美女情侣酒店| 国产精品免费无码| 欧美国产小视频| 欧美成人午夜免费视在线看片 | 色婷婷在线影院| 精品久久久久久久| 久久影院模特热| 国产精品18p| 丝袜亚洲精品中文字幕一区| 国产日韩在线精品av| 国产av无码专区亚洲a∨毛片| 国产v日产∨综合v精品视频| 久久精品五月婷婷| 91在线不卡| 午夜视频一区二区三区| 激情五月婷婷久久| 亚洲综合网站| 国产一区二区三区18| 国产精品老熟女一区二区| 亚洲每日更新| 国产一区红桃视频| 日韩在线观看视频网站| 国产精品美女视频| 男女超爽视频免费播放| av成人在线播放| 亚洲精品一区二区三区福利| 国产99在线 | 亚洲| 黄色成人av网站| 国产精品精品久久久久久| 亚洲成人一级片| 中文字幕免费在线观看视频一区| 国产96在线 | 亚洲| 日韩精品一页| 日韩精品在线免费观看| 希岛爱理中文字幕| 日韩黄色片在线观看| 国产精品区免费视频| 欧美成人xxx| 日本精品一区二区三区高清| 国产成人精品一区二区在线小狼| 欧美一区电影| 午夜精品久久久久久久白皮肤| 伊人免费在线观看| 成人99免费视频| 综合久久国产| 成人亚洲欧美| 欧美精品一区二区三区一线天视频| 3d动漫精品啪啪一区二区下载 | 天天干天天操天天干天天操| 9765激情中文在线| 欧美美女黄视频| 国产精品jizz| 亚洲天堂黄色| 91久色国产| 网友自拍视频在线| 色综合色狠狠天天综合色| 国产九九九视频| 精品一区二区三| 2018日韩中文字幕| 国产三级三级在线观看| 久久伊人中文字幕| 一本久道高清无码视频| 99热这里有精品| 国产一区二区三区日韩欧美| 亚洲国产精品午夜在线观看| 日韩激情一二三区| 日韩欧美手机在线| 婷婷电影在线观看| 亚洲电影免费观看高清| 天天色影综合网| 欧美96一区二区免费视频| 久久久久免费网| 成年网站在线视频网站| 欧美高清视频不卡网| 91视频免费在观看| 久久一区欧美| 久久99精品国产99久久| xxx.xxx欧美| 日韩欧美国产不卡| 黄视频网站免费看| 激情综合亚洲精品| 一区二区三区四区不卡| 69堂精品视频在线播放| 国产午夜精品一区理论片飘花| jizz国产在线观看| 久久久久久亚洲综合影院红桃| 久久久性生活视频| 久久精品论坛| 亚洲欧美视频在线观看| heyzo一本久久综合| 国产成人精品电影| 欧美一区二区少妇| 五月天激情综合| 最新国产精品自拍| 黑人一区二区三区四区五区| 51精品国产人成在线观看| 超碰超碰在线| 亚洲国产欧美自拍| 日本一二三区不卡| 99国产精品久| 人妻少妇被粗大爽9797pw| 亚洲桃色综合影院| 国产精彩精品视频| 精品黄色免费中文电影在线播放| 在线电影院国产精品| 中文字幕av播放| 国产91精品在线观看| 国产精品12345| 伊人久久大香线蕉无限次| 国产精品一区二区久久久| 日本中文字幕在线视频| 欧美一区二区三区在线视频 | 国产精品视频一区二区三区综合 | 久热精品在线| 欧美精品国产精品久久久 | 成人激情视频在线播放| gogo在线观看| 精品免费99久久| 丁香六月婷婷综合| 亚洲欧美日本韩国| 伦理片一区二区| 老司机精品导航| 成人在线观看www| 岛国成人av| 国产精品中文字幕在线| 欧美大胆的人体xxxx| 日韩国产一区三区| 在线免费一级片| 亚洲综合在线视频| 91视频在线网站| 久久福利视频一区二区| 亚洲国产精品成人天堂| 国产精品探花在线观看| 91在线观看免费网站| 欧美极品videos大乳护士| 在线观看欧美www| 头脑特工队2免费完整版在线观看 头脑特工队2在线播放 | 午夜精品福利影院| 成人午夜两性视频| 一个人www视频在线免费观看| 综合国产在线视频| 男女网站在线观看| 日韩一区二区在线看片| 蜜臀精品一区二区三区| 亚洲乱码日产精品bd| 久久精品老司机| 国产成人无遮挡在线视频| gogogo高清免费观看在线视频| 亚洲狠狠婷婷| 日韩人妻精品一区二区三区| 亚洲精品亚洲人成在线| 18成人免费观看网站下载| 成人免费网站视频| 色综合天天综合网国产成人网 | 日韩欧美视频一区二区| 国产在线播放精品| 成人亚洲欧美一区二区三区| 欧美电影免费观看| 日韩美女免费视频| 国产资源在线观看入口av| 日韩视频免费在线观看| 男人天堂综合| 日韩不卡中文字幕| 日本免费网站在线观看| 欧美一区二区三区不卡| 国产精品51麻豆cm传媒| 有码一区二区三区| 国产又粗又猛又爽又黄的视频四季 | 欧州一区二区三区| 国产精品看片资源| 欧美人体一区二区三区| 性色av香蕉一区二区| 久草免费在线观看| 欧美成人国产va精品日本一级| 国产午夜在线观看| 亚洲欧美激情视频| 青青青草网站免费视频在线观看| 精品国产亚洲在线| 99精品视频免费看| 日韩视频在线观看一区二区| 国产精品一区二区人人爽| 欧美日韩精品二区第二页| 日本熟妇一区二区三区| 欧美日韩一区三区四区| 伊人网视频在线| 欧美色中文字幕| 欧美三级网站在线观看| 欧美亚洲尤物久久| 国产精品久久久久久免费播放 | 国产又粗又猛视频免费| 欧美午夜精品电影| 中国a一片一级一片| 91精品国产一区二区三区| 国产麻豆精品一区| 日韩一区二区三区av| 国产av无码专区亚洲a∨毛片| 日韩三级电影网址| 青青青草网站免费视频在线观看| 亚洲欧美一区二区三区在线| 日本高清中文字幕二区在线| 亚洲欧美国产另类| 成年人在线观看视频| 免费91麻豆精品国产自产在线观看| 黄网站在线免费看| 欧美高清自拍一区| а√在线天堂官网| 91爱爱小视频k| 久久爱.com| 51国偷自产一区二区三区的来源| 成人午夜大片| 秋霞在线观看一区二区三区| 日韩在线视屏| 91九色丨porny丨国产jk| 久久久久久一区二区| www欧美激情| 国产黄色精品视频| 亚洲黄色小说在线观看| 久久影音资源网| 国产成人自拍网站| 欧美日韩人人澡狠狠躁视频| 欧美国产一级片| 在线播放中文一区| 高清一区二区三区四区| 亚洲成人高清| 中文字幕日韩视频| 男人在线资源站| 51久久精品夜色国产麻豆| 韩国三级一区| 亚洲一区二区三区xxx视频| 国产亚洲成av人片在线观黄桃| 欧美婷婷久久| 好看的av在线不卡观看| 青青在线免费观看视频| 国产一区二区久久| av小说在线观看| 中文字幕一区二区三区四区不卡 | 亚洲综合在线免费观看| 五月婷婷视频在线| 6080日韩午夜伦伦午夜伦| 天天摸天天碰天天爽天天弄| 久久在精品线影院精品国产| 亚洲国产精一区二区三区性色| 嫩草国产精品入口| 久久涩涩网站| 日韩一区二区中文| 日韩精品xxxx| 国产美女精品人人做人人爽| 野花社区视频在线观看| 成人在线视频你懂的| 亚洲免费av网站| 欧美手机在线观看| 欧美日韩一区免费| 国产视频一区二区三区四区五区| 国产视频精品免费播放| av大大超碰在线| 国产97在线|日韩| 色8久久久久| 亚洲欧洲精品在线观看| 国产欧美不卡| 国产一级二级av| 国产精品欧美久久久久无广告| 亚洲午夜无码久久久久| 亚洲激情成人网| av在线免费观看网址| 国产免费久久av| 成人久久久久| www.亚洲天堂网| 99久久久精品| 国产一级性生活| 亚洲精品720p| 毛片在线网址| 亚洲一区久久久| 国产精品传媒精东影业在线| www.日本一区| 国产精品久久影院| 欧美亚洲另类小说| 精品亚洲一区二区三区| 欧美黄色视屏| 精品久久久久久一区| 伊人精品在线| 欧美日韩一区二区三区四区五区六区| 亚洲国产毛片aaaaa无费看 | 欧美调教femdomvk| 毛片网站在线| 日韩女在线观看| 在线一级成人| 成年人在线看片| 国产人妖乱国产精品人妖| 国产一区二区视频免费| 亚洲人成电影网| 欧美色999| 亚洲午夜精品福利| 美女一区二区视频| 欧美性猛交xxxxx少妇| 69堂国产成人免费视频| av网站大全在线| αv一区二区三区| 久久精品人人| 91精品久久久久久久久久久久| 欧美在线看片a免费观看| aⅴ在线视频男人的天堂| 成人在线激情视频| 欧美1区2区| 中文字幕一区二区三区乱码不卡| 精品女厕一区二区三区| 在线激情网站| 亚洲专区在线视频| 亚洲黄色av| 精品无码国产一区二区三区51安| 在线观看亚洲精品| 亚洲天堂网在线观看视频| 青椒成人免费视频| 久久人人爽人人爽人人片av高清| 亚洲免费不卡视频| 久久久久久久久久久成人| 天堂在线精品| 日本a√在线观看| 国产精品久久久99| 99久久精品国产一区色| 日本亚洲欧洲色| 亚洲啊v在线观看| 少妇一级淫片免费放播放| 在线精品视频免费播放| 金瓶狂野欧美性猛交xxxx | 国产精品夜夜夜爽张柏芝| 国产福利不卡视频|