真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

c++11線程需要互斥量的原因是什么

本篇內(nèi)容介紹了“c++11線程需要互斥量的原因是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

成都創(chuàng)新互聯(lián)公司專業(yè)成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè),集網(wǎng)站策劃、網(wǎng)站設(shè)計(jì)、網(wǎng)站制作于一體,網(wǎng)站seo、網(wǎng)站優(yōu)化、網(wǎng)站營(yíng)銷、軟文平臺(tái)等專業(yè)人才根據(jù)搜索規(guī)律編程設(shè)計(jì),讓網(wǎng)站在運(yùn)行后,在搜索中有好的表現(xiàn),專業(yè)設(shè)計(jì)制作為您帶來(lái)效益的網(wǎng)站!讓網(wǎng)站建設(shè)為您創(chuàng)造效益。

為什么需要互斥量

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

#define _CRT_SECURE_NO_WARNINGS

#include 
#include 
#include 
#include 

// 打印機(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

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

#define _CRT_SECURE_NO_WARNINGS

#include 
#include 
#include 
#include 
#include 

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

// 打印機(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可以簡(jiǎn)化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 
#include 
#include 
#include 
#include 

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

// 打印機(jī)
void printer(const char *str)
{
    std::lock_guard 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è)線程訪問(wèn)同一個(gè)全局資源的時(shí)候,能夠確保所有其他的線程都不在同一時(shí)間內(nèi)訪問(wèn)相同的資源。也就是他確保了在同一時(shí)刻只有唯一的線程對(duì)這個(gè)資源進(jìn)行訪問(wèn)。這有點(diǎn)類似互斥對(duì)象對(duì)共享資源的訪問(wèn)的保護(hù),但是原子操作更加接近底層,因而效率更高。

#define _CRT_SECURE_NO_WARNINGS

#include 
#include 
#include 
#include 

//全局的結(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)行無(wú)鎖訪問(wèn)
        total += 1;
    }
}


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

    //線程
    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ù)的競(jìng)爭(zhēng)而導(dǎo)致每次運(yùn)行的結(jié)果都不一樣。因此,為了防止數(shù)據(jù)競(jìng)爭(zhēng)問(wèn)題,我們需要對(duì)total進(jìn)行原子操作。

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

#define _CRT_SECURE_NO_WARNINGS

#include 
#include 
#include 
#include 
#include 

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í)開(kāi)始

    //線程
    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í)長(zhǎng)點(diǎn)。

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

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

#define _CRT_SECURE_NO_WARNINGS

#include 
#include 
#include 
#include 
#include 

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

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


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

    //線程
    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線程需要互斥量的原因是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!


名稱欄目:c++11線程需要互斥量的原因是什么
文章分享:http://weahome.cn/article/iiojpi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部