国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C++11手撕線程池 call_once 單例模式 Singleton / condition_variable 與其使用場景

這篇具有很好參考價值的文章主要介紹了C++11手撕線程池 call_once 單例模式 Singleton / condition_variable 與其使用場景。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、call_once 單例模式 Singleton?

大家可以先看這篇文章:https://zh.cppreference.com/w/cpp/thread/call_once

/*
    std::call_once
    void call_once( std::once_flag& flag, Callable&& f, Args&&... args );
*/
#include <iostream>
#include <mutex>
#include <thread>

std::once_flag flag1, flag2;

void simple_do_once() {
    std::call_once(flag1, []() {
        std::cout << "簡單樣例:調(diào)用一次\n";
    });
}

void test1() {
    std::thread st1(simple_do_once);
    std::thread st2(simple_do_once);
    std::thread st3(simple_do_once);
    std::thread st4(simple_do_once);
    st1.join();
    st2.join();
    st3.join();
    st4.join();
}

void may_throw_function(bool do_throw) {
    if (do_throw) {
        std::cout << "拋出:call_once 會重試\n"; // 這會出現(xiàn)不止一次
        throw std::exception();
    }
    std::cout << "沒有拋出,call_once 不會再重試\n"; // 保證一次
}

void do_once(bool do_throw) {
    try {
        std::call_once(flag2, may_throw_function, do_throw);
    }
    catch (...) {}
}

void test2() {
    std::thread t1(do_once, true);
    std::thread t2(do_once, true);
    std::thread t3(do_once, false);
    std::thread t4(do_once, true);
    t1.join();
    t2.join();
    t3.join();
    t4.join();
}
int main() {
    test1();
    test2();
    return 0;
}

C++11手撕線程池 call_once 單例模式 Singleton / condition_variable 與其使用場景,線程池,單例模式,call_once,Singleton,手撕線程池,c++11

call_once 應(yīng)用在單例模式,以及關(guān)于單例模式我的往期文章推薦:C++ 設(shè)計模式----“對象性能“模式_愛編程的大丙 設(shè)計模式-CSDN博客https://heheda.blog.csdn.net/article/details/131466271

懶漢是一開始不會實例化,什么時候用就什么時候new,才會實例化
餓漢在一開始類加載的時候就已經(jīng)實例化,并且創(chuàng)建單例對象,以后只管用即可
--來自百度文庫
#include <iostream>
#include <thread>
#include <mutex>
#include <string>

// 日志類:在整個項目中,有提示信息或者有報錯信息,都通過這個類來打印
// 這些信息到日志文件,或者打印到屏幕上。顯然,全局只需要一個日志類的
// 對象就可以完成所有的打印操作了。不需要第二個類來操作,這個時候就可以
// 使用單例模式來設(shè)計它

std::once_flag onceFlag;
class Log {
public:
    Log(const Log& log) = delete;
    Log& operator=(const Log& log) = delete;
    // static Log& getInstance() { 
    //     static Log log; // 餓漢模式
    //     return log;
    // }
    static Log& getInstance() { // 懶漢模式
        std::call_once(onceFlag, []() {
            std::cout << "簡單樣例:調(diào)用一次\n";
            log = new Log;
        });
        return *log;
    }
    void PrintLog(std::string msg) {
        std::cout << __TIME__ << msg << std::endl;
    }
private:
    Log() {};
    static Log* log; 
};
Log* Log::log = nullptr;

void func() {
    Log::getInstance().PrintLog("這是一個提示");
}

void print_error() {
    Log::getInstance().PrintLog("發(fā)現(xiàn)一個錯誤");
}

void test() {
    std::thread t1(print_error);
    std::thread t2(print_error);
    std::thread t3(func);
    t1.join();
    t2.join();
    t3.join();
}

int main() {
    test();
    return 0;
}

C++11手撕線程池 call_once 單例模式 Singleton / condition_variable 與其使用場景,線程池,單例模式,call_once,Singleton,手撕線程池,c++11

二、condition_variable 與其使用場景

#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>
#include <queue>

std::queue<int> queue;
std::condition_variable cond;
std::mutex mtx;

void Producer() {
    for (int i = 0; i < 10; i++) {
        {
            std::unique_lock<std::mutex> locker(mtx);
            queue.push(i);
            cond.notify_one();
            std::cout << "Producer : " << i << std::endl;
        }
        std::this_thread::sleep_for(std::chrono::microseconds(100));
    }
}

void Consumer() {
    while (1) {
        std::unique_lock<std::mutex> locker(mtx);
        cond.wait(locker, []() {
            return !queue.empty();
            });
        int value = queue.front();
        queue.pop();
        std::cout << "Consumer :" << value << std::endl;
    }
}

int main() {
    std::thread t1(Producer);
    std::thread t2(Consumer);
    t1.join();
    t2.join();
    return 0;
}

C++11手撕線程池 call_once 單例模式 Singleton / condition_variable 與其使用場景,線程池,單例模式,call_once,Singleton,手撕線程池,c++11

三、C++11 手撕線程池 + 單例模式(call_once)

  • ThreadPool.h
#include <iostream>
#include <thread>
#include <mutex>
#include <string>
#include <condition_variable>
#include <queue>
#include <vector>
#include <functional>
std::once_flag onceFlag;
class ThreadPool {
private:
    ThreadPool();
public:
    ThreadPool(const ThreadPool& obj) = delete;
    ThreadPool& operator=(const ThreadPool& obj) = delete;
    static ThreadPool& getInstance();
    ~ThreadPool();
    template<class F, class... Args>
    void enqueue(F&& f, Args&&... args) {
        std::function<void()> task =
            std::bind(std::forward<F>(f), std::forward<Args>(args)...);
        {
            std::unique_lock<std::mutex> locker(mtx);
            tasks.emplace(std::move(task));
        }
        cond.notify_one();
    }
    inline void setNum(int num) {
        threadNum = num;
    }
    inline void printNum() {
        std::cout << "線程數(shù)量為:" << threadNum << std::endl;
    }
private:
    static ThreadPool* pool;
    std::vector<std::thread> threads;// 線程數(shù)組
    std::queue<std::function<void()>> tasks;//任務(wù)隊列
    std::mutex mtx;// 互斥鎖
    std::condition_variable cond;//條件變量
    bool stop;
    int threadNum;// 線程數(shù)量
};

  • ThreadPool.cpp
#include "ThreadPool.h"
#include <iostream>
ThreadPool* ThreadPool::pool = nullptr;
ThreadPool::ThreadPool() {
    stop = false;
    threadNum = 4;
    for (int i = 0; i < threadNum; ++i) {
        threads.emplace_back([this]() {
            while (1) {
                std::unique_lock<std::mutex> locker(mtx);
                cond.wait(locker, [this]() {
                    return !tasks.empty() || stop;
                    });
                if (stop && tasks.empty()) {
                    return;
                }
                std::function<void()> task(std::move(tasks.front()));
                tasks.pop();
                task();// 執(zhí)行這個任務(wù)
            }
            });
    }
}

ThreadPool::~ThreadPool() {
    {
        std::unique_lock<std::mutex> locker(mtx);
        stop = true;
    }
    cond.notify_all();
    for (auto& t : threads) {
        t.join();
    }
}

ThreadPool& ThreadPool::getInstance() { // 懶漢模式
    std::call_once(onceFlag, []() {
        std::cout << "懶漢模式:調(diào)用一次" << std::endl;
        pool = new ThreadPool();
        });
    return *pool;
}
  • ?main.cpp
#include <iostream>
#include "ThreadPool.h"
#include <thread>
void addTask() {
    ThreadPool& pool = ThreadPool::getInstance();
    pool.setNum(8);
    for (int i = 0; i < 10; ++i) {
        pool.enqueue([i]() {
            std::cout << "task : " << i << " is runing!" << std::endl;
            std::this_thread::sleep_for(std::chrono::microseconds(10));
            std::cout << "task : " << i << " is done!" << std::endl;
            });
    }
}

void test() {
    std::thread t1(addTask);
    std::thread t2(addTask);
    std::thread t3(addTask);
    t1.join();
    t2.join();
    t3.join();
}

int main() {
    test();
    return 0;
}

運行結(jié)果:

懶漢模式:調(diào)用一次
task : 0 is runing!
task : 0 is done!
task : 0 is runing!
task : 0 is done!
task : 1 is runing!
task : 1 is done!
task : 0 is runing!
task : 0 is done!
task : 1 is runing!
task : 1 is done!
task : 1 is runing!
task : 1 is done!
task : 2 is runing!
task : 2 is done!
task : 3 is runing!
task : 3 is done!
task : 2 is runing!
task : 2 is done!
task : 4 is runing!
task : 4 is done!
task : 3 is runing!
task : 3 is done!
task : 2 is runing!
task : 2 is done!
task : 3 is runing!
task : 3 is done!
task : 4 is runing!
task : 4 is done!
task : 5 is runing!
task : 5 is done!
task : 4 is runing!
task : 4 is done!
task : 5 is runing!
task : 5 is done!
task : 6 is runing!
task : 6 is done!
task : 7 is runing!
task : 7 is done!
task : 8 is runing!
task : 8 is done!
task : 9 is runing!
task : 9 is done!
task : 6 is runing!
task : 6 is done!
task : 7 is runing!
task : 7 is done!
task : 5 is runing!
task : 5 is done!
task : 6 is runing!
task : 6 is done!
task : 8 is runing!
task : 8 is done!
task : 9 is runing!
task : 9 is done!
task : 7 is runing!
task : 7 is done!
task : 8 is runing!
task : 8 is done!
task : 9 is runing!

D:\Work\vsproject\c++11\x64\Debug\c++11.exe (進程 32636)已退出,代碼為 0。
要在調(diào)試停止時自動關(guān)閉控制臺,請啟用“工具”->“選項”->“調(diào)試”->“調(diào)試停止時自動關(guān)閉控制臺”。
按任意鍵關(guān)閉此窗口. . .
  • 關(guān)于智能指針的回顧,可以看我的往期文章了解一下喔!

獨占指針:unique_ptr 與 函數(shù)調(diào)用 筆記-CSDN博客https://heheda.blog.csdn.net/article/details/135841140計數(shù)指針:shared_ptr (共享指針)與函數(shù) 筆記-CSDN博客https://heheda.blog.csdn.net/article/details/135851596shared_ptr 與 unique_ptr 的轉(zhuǎn)換 筆記-CSDN博客https://heheda.blog.csdn.net/article/details/135853468weak_ptr 與 一個難發(fā)現(xiàn)的錯誤(循環(huán)依賴問題)筆記-CSDN博客https://heheda.blog.csdn.net/article/details/135854106文章來源地址http://www.zghlxwxcb.cn/news/detail-818483.html

到了這里,關(guān)于C++11手撕線程池 call_once 單例模式 Singleton / condition_variable 與其使用場景的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 單例模式(Singleton)

    單例模式(Singleton)

    單例是一種創(chuàng)建型設(shè)計模式,讓你能夠保證一個類只有一個實例,并提供一個訪問該實例的全局節(jié)點。 1. 問題 單例模式同時解決了兩個問題,所以違反了單一職責原則: 保證一個類只有一個實例 。 為該實例提供一個全局訪問節(jié)點 。 為什么會有人想要控制一個類所擁有的實

    2024年02月11日
    瀏覽(17)
  • 10-單例模式(Singleton)

    保證一個類只有一個實例,并提供一個訪問它的全局訪問點 優(yōu)點:安全且在多線程情況下保持高性能。 描述:這種方式能達到雙檢鎖方式一樣的功效,但實現(xiàn)更簡單。對靜態(tài)域使用延遲初始化,應(yīng)使用這種方式而不是雙檢鎖方式。這種方式只適用于靜態(tài)域的情況,雙檢鎖方

    2024年02月03日
    瀏覽(50)
  • 單例模式(Singleton)

    單例模式(Singleton)

    單例模式 保證一個類僅有一個實例 ,并 提供一個全局訪問點來訪問它 ,這個類稱為單例類??梢?,在實現(xiàn)單例模式時,除了保證一個類只能創(chuàng)建一個實例外,還需提供一個全局訪問點。 為提供一個全局訪問點,可以使用全局變量,但全局變量無法禁止用戶實例化多個對象

    2024年02月14日
    瀏覽(19)
  • 設(shè)計模式四:單例模式(Singleton)

    單例模式,是一種常用的軟件設(shè)計模式。在它的核心結(jié)構(gòu)中只包含一個被稱為單例的特殊類。 通過單例模式可以保證系統(tǒng)中,應(yīng)用該模式的類一個類只有一個實例。即一個類只有一個對象實例。 單例模式是設(shè)計模式中最簡單的形式之一。這一模式的目的是使得類的一個對象

    2024年02月15日
    瀏覽(24)
  • 單例模式(Singleton Pattern)

    單例模式(Singleton Pattern)

    單例模式(Singleton Pattern)是結(jié)構(gòu)最簡單的設(shè)計模式,它的 核心結(jié)構(gòu)中只包含一個被稱為單例類的特殊類 。通過 單例模式可以確保系統(tǒng)中一個類只有一個實例 ,且該實例易于被外界訪問,從而方便對實例個數(shù)的控制并節(jié)約系統(tǒng)資源。 如何確保一個類只有一個實例并且這個實

    2024年02月03日
    瀏覽(24)
  • 單例模式(Singleton Pattern)

    單例模式(Singleton Pattern)是一種創(chuàng)建型設(shè)計模式,用于確保一個類只有一個實例,并提供全局訪問點來獲取該實例。 單例模式的特點是: 只允許類創(chuàng)建一個實例。 提供一個全局訪問點來獲取該實例。 對外部代碼隱藏實例化過程,使得外部代碼無法直接創(chuàng)建實例。 以下是一

    2024年02月15日
    瀏覽(21)
  • java設(shè)計模式-單例模式(Singleton)

    單例模式(Singleton)就是一個類只能有一個實例,自行實例化,并向系統(tǒng)提供這一實例,這個類就是單例類。單例模式的特點: 一個類只能有一個實例; 單例類自己實例化; 單例類給其它對象提供這個單一實例。 資源管理類經(jīng)常被設(shè)計為單例模式,例如管理屬性文件的類。

    2024年02月15日
    瀏覽(19)
  • C++ 中的單例模式singleton

    在面向?qū)ο缶幊讨?,設(shè)計模式是解決常見問題的最佳實踐。單例模式是其中之一,它確保一個類只有一個實例,并提供一個全局訪問點來獲取該實例。在本文中,我們將詳細介紹 C++ 中的單例模式。 單例模式是一種設(shè)計模式,它限制一個類只能創(chuàng)建一個對象。這個模式通常用

    2024年02月21日
    瀏覽(23)
  • 大話設(shè)計模式——9.單例模式(Singleton Pattern)

    大話設(shè)計模式——9.單例模式(Singleton Pattern)

    簡介 確保一個類只有一個實例,并提供全局訪問點來獲取該實例,是最簡單的設(shè)計模式。 UML圖: 單例模式共有兩種創(chuàng)建方式: 餓漢式(線程安全) 提前創(chuàng)建實例,好處在于該實例全局唯一,不存在線程沖突;壞處在于未使用時也會占用內(nèi)存資源。 懶漢式(原生寫法存在線

    2024年04月12日
    瀏覽(52)
  • 《游戲編程模式》學習筆記(六)單例模式 Singleton Pattern

    保證一個類只有一個實例,并且提供了訪問該實例的全局訪問點。 定義這種東西一般都是不說人話的,要想要理解這句話的意思,我們得把它揉開了才能搞明白。 我們先看前半句 “保證一個類只有一個實例”,單例一般使用類來實現(xiàn),也就是說,這個單例類,其有且只能有

    2024年02月12日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包