最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談c++11線程的互斥量

 更新時(shí)間:2021年06月08日 15:22:52   作者:lsgxeva  
互斥量是個(gè)類對(duì)象,理解成一把鎖(保護(hù)共享數(shù)據(jù),其他想操作共享數(shù)據(jù)的線程必須等待解鎖),互斥量使用要小心,保護(hù)數(shù)據(jù)不多也不少,少了則沒達(dá)到保護(hù)效果,多了則影響效率。本文將介紹c++11線程的互斥量,感興趣的同學(xué),可以參考下。

為什么需要互斥量

在多任務(wù)操作系統(tǒng)中,同時(shí)運(yùn)行的多個(gè)任務(wù)可能都需要使用同一種資源。這個(gè)過程有點(diǎn)類似于,公司部門里,我在使用著打印機(jī)打印東西的同時(shí)(還沒有打印完),別人剛好也在此刻使用打印機(jī)打印東西,如果不做任何處理的話,打印出來的東西肯定是錯(cuò)亂的。

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <chrono>
#include <thread>

// 打印機(jī)
void printer(const char *str)
{
    while(*str != '\0')
    {
        std::cout << *str;
        str++;
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
    std::cout << std::endl;
}

// 線程一
void func1()
{
    const char *str = "hello";
    printer(str);
}

// 線程二
void func2()
{
    const char *str = "world";
    printer(str);
}


void mytest()
{
    std::thread t1(func1);
    std::thread t2(func2);

    t1.join();
    t2.join();

    return;
}

int main()
{
    mytest();

    system("pause");
    return 0;
}

獨(dú)占互斥量std::mutex

互斥量的基本接口很相似,一般用法是通過lock()方法來阻塞線程,直到獲得互斥量的所有權(quán)為止。在線程獲得互斥量并完成任務(wù)之后,就必須使用unlock()來解除對(duì)互斥量的占用,lock()和unlock()必須成對(duì)出現(xiàn)。try_lock()嘗試鎖定互斥量,如果成功則返回true, 如果失敗則返回false,它是非阻塞的。

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <mutex>

std::mutex g_lock; //全局互斥鎖對(duì)象,#include <mutex>

// 打印機(jī)
void printer(const char *str)
{
    g_lock.lock(); //上鎖
    while(*str != '\0')
    {
        std::cout << *str;
        str++;
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
    std::cout << std::endl;
    g_lock.unlock(); // 解鎖
}

// 線程一
void func1()
{
    const char *str = "hello";
    printer(str);
}

// 線程二
void func2()
{
    const char *str = "world";
    printer(str);
}


void mytest()
{
    std::thread t1(func1);
    std::thread t2(func2);

    t1.join();
    t2.join();

    return;
}

int main()
{
    mytest();

    system("pause");
    return 0;
}

使用std::lock_guard可以簡化lock/unlock的寫法,同時(shí)也更安全,因?yàn)閘ock_guard在構(gòu)造時(shí)會(huì)自動(dòng)鎖定互斥量,而在退出作用域后進(jìn)行析構(gòu)時(shí)就會(huì)自動(dòng)解鎖,從而避免忘了unlock操作。

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <mutex>

std::mutex g_lock; //全局互斥鎖對(duì)象,#include <mutex>

// 打印機(jī)
void printer(const char *str)
{
    std::lock_guard<std::mutex> locker(g_lock); // lock_guard 上鎖
    while(*str != '\0')
    {
        std::cout << *str;
        str++;
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
    std::cout << std::endl;
    // 即將推出作用域 lock_guard 會(huì)自動(dòng)解鎖
}

// 線程一
void func1()
{
    const char *str = "hello";
    printer(str);
}

// 線程二
void func2()
{
    const char *str = "world";
    printer(str);
}


void mytest()
{
    std::thread t1(func1);
    std::thread t2(func2);

    t1.join();
    t2.join();

    return;
}

int main()
{
    mytest();

    system("pause");
    return 0;
}

原子操作

所謂的原子操作,取的就是“原子是最小的、不可分割的最小個(gè)體”的意義,它表示在多個(gè)線程訪問同一個(gè)全局資源的時(shí)候,能夠確保所有其他的線程都不在同一時(shí)間內(nèi)訪問相同的資源。也就是他確保了在同一時(shí)刻只有唯一的線程對(duì)這個(gè)資源進(jìn)行訪問。這有點(diǎn)類似互斥對(duì)象對(duì)共享資源的訪問的保護(hù),但是原子操作更加接近底層,因而效率更高。

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <chrono>
#include <thread>

//全局的結(jié)果數(shù)據(jù)
long total = 0;

//點(diǎn)擊函數(shù)
void func()
{
    for(int i = 0;  i < 1000000; ++i)
    {
        // 對(duì)全局?jǐn)?shù)據(jù)進(jìn)行無鎖訪問
        total += 1;
    }
}


void mytest()
{
    clock_t start = clock();    // 計(jì)時(shí)開始

    //線程
    std::thread t1(func);
    std::thread t2(func);

    t1.join();
    t2.join();

    clock_t end = clock();    // 計(jì)時(shí)結(jié)束

    std::cout << "total = " << total << std::endl;
    std::cout << "time = " << end-start << " ms" << std::endl;


    return;
}

int main()
{
    mytest();

    system("pause");
    return 0;
}

由于線程間對(duì)數(shù)據(jù)的競爭而導(dǎo)致每次運(yùn)行的結(jié)果都不一樣。因此,為了防止數(shù)據(jù)競爭問題,我們需要對(duì)total進(jìn)行原子操作。

通過互斥鎖進(jìn)行原子操作:

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <mutex>

std::mutex g_lock;

//全局的結(jié)果數(shù)據(jù)
long total = 0;

//點(diǎn)擊函數(shù)
void func()
{
    for(int i = 0;  i < 1000000; ++i)
    {
        g_lock.lock(); // 加鎖
        total += 1;
        g_lock.unlock(); // 加鎖
    }
}


void mytest()
{
    clock_t start = clock();    // 計(jì)時(shí)開始

    //線程
    std::thread t1(func);
    std::thread t2(func);

    t1.join();
    t2.join();

    clock_t end = clock();    // 計(jì)時(shí)結(jié)束

    std::cout << "total = " << total << std::endl;
    std::cout << "time = " << end-start << " ms" << std::endl;


    return;
}

int main()
{
    mytest();

    system("pause");
    return 0;
}

每次運(yùn)行的結(jié)果都一樣,只是耗時(shí)長點(diǎn)。

在新標(biāo)準(zhǔn)C++11,引入了原子操作的概念。

如果我們?cè)诙鄠€(gè)線程中對(duì)這些類型的共享資源進(jìn)行操作,編譯器將保證這些操作都是原子性的,也就是說,確保任意時(shí)刻只有一個(gè)線程對(duì)這個(gè)資源進(jìn)行訪問,編譯器將保證多個(gè)線程訪問這個(gè)共享資源的正確性。從而避免了鎖的使用,提高了效率。

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <atomic>

//原子數(shù)據(jù)類型
std::atomic<long> total(0); //需要頭文件 #include <atomic>

//點(diǎn)擊函數(shù)
void func()
{
    for(int i = 0;  i < 1000000; ++i)
    {
        // 
        total += 1;
    }
}


void mytest()
{
    clock_t start = clock();    // 計(jì)時(shí)開始

    //線程
    std::thread t1(func);
    std::thread t2(func);

    t1.join();
    t2.join();

    clock_t end = clock();    // 計(jì)時(shí)結(jié)束

    std::cout << "total = " << total << std::endl;
    std::cout << "time = " << end-start << " ms" << std::endl;


    return;
}

int main()
{
    mytest();

    system("pause");
    return 0;
}

原子操作的實(shí)現(xiàn)跟普通數(shù)據(jù)類型類似,但是它能夠在保證結(jié)果正確的前提下,提供比mutex等鎖機(jī)制更好的性能。

以上就是淺談c++11線程的互斥量的詳細(xì)內(nèi)容,更多關(guān)于c++11線程的互斥量的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Visual?C++?6.0添加一個(gè)對(duì)話框的實(shí)現(xiàn)步驟

    Visual?C++?6.0添加一個(gè)對(duì)話框的實(shí)現(xiàn)步驟

    VC6.0是微軟公司推出的一款集成開發(fā)環(huán)境,本文主要介紹了Visual?C++?6.0添加一個(gè)對(duì)話框的實(shí)現(xiàn)步驟,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • C語言實(shí)現(xiàn)歌手比賽系統(tǒng)

    C語言實(shí)現(xiàn)歌手比賽系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)歌手比賽系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • c語言單詞搜索的實(shí)現(xiàn)

    c語言單詞搜索的實(shí)現(xiàn)

    本文主要介紹了c語言單詞搜索的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • C++中的ilst使用以及模擬實(shí)現(xiàn)

    C++中的ilst使用以及模擬實(shí)現(xiàn)

    list是一個(gè)類模板,加<類型>實(shí)例化才是具體的類,可以在任意位置進(jìn)行插入和刪除的序列式容器,本文將通過代碼示例給大家介紹一下C++中的ilst使用以及模擬實(shí)現(xiàn),需要的朋友可以參考下
    2023-08-08
  • C語言中關(guān)于計(jì)算字符串長度的幾種方式

    C語言中關(guān)于計(jì)算字符串長度的幾種方式

    這篇文章主要介紹了C語言中關(guān)于計(jì)算字符串長度的幾種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • VS2019實(shí)現(xiàn)C++的第一個(gè)MFC程序

    VS2019實(shí)現(xiàn)C++的第一個(gè)MFC程序

    本文主要介紹了VS2019實(shí)現(xiàn)C++的第一個(gè)MFC程序,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-06-06
  • OpenCV實(shí)現(xiàn)圖像邊緣檢測

    OpenCV實(shí)現(xiàn)圖像邊緣檢測

    這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)圖像邊緣檢測,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • c++基礎(chǔ)使用STL的注意點(diǎn)詳解

    c++基礎(chǔ)使用STL的注意點(diǎn)詳解

    這篇文章主要為大家介紹了c++基礎(chǔ)使用STL的注意點(diǎn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • 深入理解C/C++中的寫時(shí)拷貝

    深入理解C/C++中的寫時(shí)拷貝

    這篇文章主要給大家介紹了C/C++中寫時(shí)拷貝的相關(guān)資料,所謂寫時(shí)拷貝也就是拖延版的深拷貝,下面文章中介紹的非常清楚,需要的朋友可以參考學(xué)習(xí),下面來一起看看吧。
    2017-03-03
  • C語言詳細(xì)講解二分查找用法

    C語言詳細(xì)講解二分查找用法

    二分查找法,又叫做折半查找法,它是一種效率較高的查找方法。但是,折半查找要求線性表必須采用順序存儲(chǔ)結(jié)構(gòu),而且表中元素按關(guān)鍵字有序排列
    2022-04-04

最新評(píng)論

吉首市| 神木县| 新津县| 黄冈市| 沙坪坝区| 米泉市| 永城市| 赤水市| 赤水市| 普兰县| 商城县| 河池市| 北川| 泌阳县| 集贤县| 枝江市| 普洱| 改则县| 青龙| 南城县| 衡东县| 旬阳县| 南阳市| 凤凰县| 多伦县| 东至县| 山东省| 睢宁县| 白银市| 平谷区| 盖州市| 昌平区| 南昌县| 仲巴县| 大城县| 彰化县| 土默特左旗| 广水市| 遵义县| 越西县| 崇左市|