久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C++11undefinedThread多線程的學(xué)習(xí)心得與問題

 禁忌石 2019-06-15

C++11 ,,封裝了thread的多線程的類,,這樣對多線程的使用更加方便。

多線程的原理我不加贅述,,可以參看操作系統(tǒng)等參考書,。

多線程代碼可以最大化利用計算機性能資源,提高代碼的運行效率,是常用優(yōu)化方法,。

我不是C++大神,,初學(xué)階段的菜鳥而已,很多問題我還是不理解當(dāng)中的原理,,寫這篇博客的原因,,也是記錄自己的學(xué)習(xí)心得和思路,供自己日后自己思考,。

首先從簡單的問題入手,,如何寫一個多線程的C++代碼?

復(fù)制代碼
#include<iostream>
#include<thread>

void fun(int a){
    a++;
}

int main(){

    int a=0;

    std::thread t(fun,a);  //創(chuàng)建一個線程t,t調(diào)用函數(shù)fun,a作為fun的參數(shù),,也要寫到thread的構(gòu)造函數(shù)當(dāng)中,;
t.join(); //啟動線程t,并且阻塞主線程,等到線程t運行結(jié)束后,,再繼續(xù)運行主線程,; std::cout
<<a<<std::endl; }
復(fù)制代碼

上面這段代碼是最簡單的多線程代碼,調(diào)用thread類,,并利用了thread的構(gòu)造函數(shù)創(chuàng)建一個線程t,thread類的構(gòu)造函數(shù)重載了很多,,后面會繼續(xù)說到,。

在這里要說一下,thread類當(dāng)中的兩個成員函數(shù),,join()和detach(),。這兩個成員的作用就像上面代碼的注釋那樣,啟動新生成的線程的,,但是區(qū)別在于join()函數(shù)是啟動子線程而阻塞主線程,,當(dāng)子線程運行結(jié)束后,才會繼續(xù)運行主線程,。相比之下,,detach()函數(shù)的作用是啟動子線程,并且讓子線程和主線程分離,,子線程和主線程各運行各的,,雖然兩個線程會因為共享內(nèi)存池的原因在操作系統(tǒng)的層面發(fā)生發(fā)生阻塞等關(guān)系,但是在代碼層次上,,兩個線程并不存在誰阻塞誰,,很可能主線程已經(jīng)運行結(jié)束了,子線程還在運行,。

接下來,,我們要說一下類當(dāng)中的成員函數(shù)如何初始化thread類的構(gòu)造函數(shù)。

對于類的成員函數(shù),,我們需要給出類對象的地址:

復(fù)制代碼
#include<iostream>
#include<thread>


class A{

public:

    void fun(int a,int b){

        std::cout<<"this is A thread!"<<a<<std::endl;
    }
};

int main(){

    int k=0;

    A a;

    std::thread t(&A::fun,a,k,k+1);   
    t.join();

}
復(fù)制代碼
std::thread t(&A::fun,a,k,k+1);  這個地方就可以看出thread類的構(gòu)造對于成員函數(shù)的重載了,,std::thread t(函數(shù)(成員函數(shù))地址,,對象地址,成員函數(shù)的參數(shù)1,,參數(shù)2,,參數(shù)3...)。
相比非成員函數(shù),,成員函數(shù)需要給出類實例化對象的地址,,如果該線程是在同一類的某一成員函數(shù)當(dāng)中被構(gòu)造,則直接用this關(guān)鍵字代替即可,。

其實,,我在寫成員函數(shù)的多線程代碼的時候,發(fā)現(xiàn)成員函數(shù)的需要傳遞的參數(shù)太多會使thread類的構(gòu)造函數(shù)重載失敗,,我測試了一下,,成員函數(shù)最多只能傳遞4個參數(shù),也就說std::thread類的構(gòu)造函數(shù)最多只能重載6個參數(shù),。
這一點,,我并沒有找到相關(guān)文檔得到證實,只是在寫代碼的時候發(fā)現(xiàn)成員函數(shù)傳遞參數(shù)太多,,會一直編譯不通過,,偶然間發(fā)現(xiàn)這個點的,具體到底對不對,,我也不是很確定,。

其次,我們要說一下加鎖和解鎖的問題,。
因為我們創(chuàng)造的每一個線程只要在一個進程內(nèi),,都是共享內(nèi)存池的,這樣在讀寫數(shù)據(jù)可能會發(fā)生混亂,。
C++11提供了mutex類進行加鎖和解鎖,。
復(fù)制代碼
#include<iostream>
#include<thread>
#include<mutex>

std::mutex mut;

class A{

public:

    volatile int temp;

    A(){
        temp=0;
    }

    void fun(int num){

        int count=10;
        while(count>0){

            mut.lock();
            temp++;
            std::cout<<"thread_"<<num<<"...temp="<<temp<<std::endl;
            mut.unlock();

            count--;
        }
    }

    void thread_run(){
            std::thread t1(&A::fun,this,1);   

            std::thread t2(&A::fun,this,2);

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

int main(){

    A a;

    a.thread_run();
}
復(fù)制代碼

然后,我們說一下volatile關(guān)鍵字,。

volatile和const關(guān)鍵很相似,,都是修飾變量的,只是二者功能不一樣,。
volatile在多線程當(dāng)中經(jīng)常使用,,因為在某一線程多次調(diào)用某一個變量,編譯器會進行優(yōu)化,,將該變量存放在在寄存器當(dāng)中,,不會每次都從內(nèi)存當(dāng)中讀入。果然該變量同時在其他線程當(dāng)中被修改,這樣就會發(fā)生臟讀取錯誤,。

而加上volatile修飾,,則會提醒編譯器,這個變量可能會被改變,,不能存放到寄存器當(dāng)中,,需要每次都從內(nèi)存當(dāng)中讀取。
最后,,我們說一下join()和detach()的使用技巧,。
join及detach

上述例子中已經(jīng)用到了join和detach,以下對兩者進行說明,。 
對于C++程序而言,,你的main函數(shù)就是你的主線程,主線程在任何需要的時候都可以創(chuàng)建新的線程,,當(dāng)線程執(zhí)行完畢時,,自動終止線程;當(dāng)進程結(jié)束時,,所有線程都必須終止,。

所謂join就是主線程在調(diào)用join方法的位置等待子線程會合,會合之后執(zhí)行下一步操作,。

所謂detach就是,,主線程將不等待子線程的會合,自己直接結(jié)束生命,,子線程未執(zhí)行完也不報錯,會自己在執(zhí)行完畢后會退出,。

如果某個線程,,不聲明以上兩者之一,但是在主線程結(jié)束之前又沒有執(zhí)行完畢,,程序執(zhí)行時會崩潰,。
--------------------- 
作者:yucicheung 
來源:CSDN 
原文:https://blog.csdn.net/yucicheung/article/details/82466302 
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接,!

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多