欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

4.c++語(yǔ)言級(jí)別的多線(xiàn)程編程

通過(guò)thread類(lèi)編寫(xiě)C++多線(xiàn)程程序

線(xiàn)程內(nèi)容:

創(chuàng)新互聯(lián)專(zhuān)注于雞澤企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè)公司,商城網(wǎng)站建設(shè)。雞澤網(wǎng)站建設(shè)公司,為雞澤等地區(qū)提供建站服務(wù)。全流程定制網(wǎng)站設(shè)計(jì),專(zhuān)業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專(zhuān)業(yè)和態(tài)度為您提供的服務(wù)

1、如何創(chuàng)建啟動(dòng)一個(gè)線(xiàn)程?

? std::thread定義一個(gè)線(xiàn)程對(duì)象,傳入線(xiàn)程所需的線(xiàn)程函數(shù)和參數(shù),線(xiàn)程自動(dòng)開(kāi)啟

2、子線(xiàn)程如何結(jié)束?

? 子線(xiàn)程函數(shù)運(yùn)行完成,線(xiàn)程就結(jié)束了

3、主線(xiàn)程如何處理子線(xiàn)程

? t.join() : 等待t線(xiàn)程結(jié)束,當(dāng)前線(xiàn)程繼續(xù)往下運(yùn)行

? t.detach() : 把t線(xiàn)程設(shè)置為分離線(xiàn)程,主線(xiàn)程結(jié)束,整個(gè)進(jìn)程結(jié)束,所有子線(xiàn)程都自動(dòng)結(jié)束

#include <thread>

void threadHandler1(int time){
    std::this_thread::sleep_for(std::chrono::seconds(time));
    std::cout<<"call thread1"<<std::endl;
}

void threadHandler2(int time){
    std::this_thread::sleep_for(std::chrono::seconds(time));
    std::cout<<"call thread2"<<std::endl;
}

int main(){
    std::thread t1(threadHandler1,2);
    std::thread t2(threadHandler2,3);
    /*t1.join();
    t2.join();*/
    t1.detach();
    t2.join();
    std::cout<<"main thread done!"<<std::endl;
    return 0;
}
/*
打印輸出:
call thread1
call thread2
main thread done!
*/

線(xiàn)程間的互斥鎖mutex和lock_guard

上鎖常用lock_guard,他是對(duì)mutex的封裝,出作用域后會(huì)自動(dòng)析構(gòu),析構(gòu)的時(shí)候會(huì)釋放鎖,構(gòu)造函數(shù)會(huì)上鎖

普通的互斥鎖是:

std::mutex mtx;
mtx.lock();
//臨界區(qū)
mtx.unlock();

使用lock_guard是這樣:

{
	std::lock_guard<std::mutex> lockGuard(mtx);//出作用域后會(huì)析構(gòu)解鎖,默認(rèn)構(gòu)造是加鎖
	//臨界區(qū)
}

互斥鎖的應(yīng)用:

//模擬買(mǎi)票
int ticketCount=;
std::mutex mtx;

void sellTicket(int index){
    while(ticketCount>0){//可能會(huì)發(fā)生提前進(jìn)入循環(huán)的情況,所以需要在循環(huán)內(nèi)再加一層判斷
//        mtx.lock();
        {//
            std::lock_guard<std::mutex> lockGuard(mtx);//出作用域后會(huì)析構(gòu)解鎖,默認(rèn)構(gòu)造是加鎖
            if(ticketCount>0){
                //下面兩句屬于臨界區(qū)代碼,該代碼段中的操作必須是原子操作,要保證線(xiàn)程之間要互斥。
                std::cout<<"窗口"<<index<<"賣(mài)出第"<<ticketCount<<"張票"<<std::endl;
                ticketCount--;
            }
        }
//        mtx.unlock();
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
}

int main(){
    std::list<std::thread> threadList;

    for(int i=1;i<=3;++i){
        threadList.push_back(std::thread(sellTicket,i));
    }

    for(auto &th:threadList){
        th.join();
    }

    std::cout<<"main thread done!"<<std::endl;
    return 0;
}

線(xiàn)程間的同步通訊機(jī)制

生產(chǎn)者,消費(fèi)者線(xiàn)程模型

C++ STl中的所有容器都不是線(xiàn)程安全的

使用條件變量condition_variable做線(xiàn)程間的通信操作

線(xiàn)程間同步通信最典型的例子就是生產(chǎn)者-消費(fèi)者模型,生產(chǎn)者線(xiàn)程生產(chǎn)出產(chǎn)品以后,會(huì)通知消費(fèi)者線(xiàn)程去消費(fèi)產(chǎn)品;如果消費(fèi)者線(xiàn)程去消費(fèi)產(chǎn)品,發(fā)現(xiàn)還沒(méi)有產(chǎn)品生產(chǎn)出來(lái),它需要通知生產(chǎn)者線(xiàn)程趕快生產(chǎn)產(chǎn)品,等生產(chǎn)者線(xiàn)程生產(chǎn)出產(chǎn)品以后,消費(fèi)者線(xiàn)程才能繼續(xù)往下執(zhí)行。

C++11 線(xiàn)程庫(kù)提供的條件變量condition_variable,就是Linux平臺(tái)下的Condition Variable機(jī)制,用于解決線(xiàn)程間的同步通信問(wèn)題,下面通過(guò)代碼演示一個(gè)生產(chǎn)者-消費(fèi)者線(xiàn)程模型,仔細(xì)分析代碼:

// 定義互斥鎖(條件變量需要和互斥鎖一起使用)
std::mutex mtx;
// 定義條件變量(用來(lái)做線(xiàn)程間的同步通信)
std::condition_variable cv;
// 定義vector容器,作為生產(chǎn)者和消費(fèi)者共享的容器
std::vector<int> vec;

// 生產(chǎn)者線(xiàn)程函數(shù)
void producer()
{
    // 生產(chǎn)者每生產(chǎn)一個(gè),就通知消費(fèi)者消費(fèi)一個(gè)
    for (int i = 1; i <= 10; ++i)
    {
        // 獲取mtx互斥鎖資源
        std::unique_lock<std::mutex> lock(mtx);

        // 如果容器不為空,代表還有產(chǎn)品未消費(fèi),等待消費(fèi)者線(xiàn)程消費(fèi)完,再生產(chǎn)
        while (!vec.empty())
        {
            // 判斷容器不為空,進(jìn)入等待條件變量的狀態(tài),釋放mtx鎖,
            // 讓消費(fèi)者線(xiàn)程搶到鎖能夠去消費(fèi)產(chǎn)品
            cv.wait(lock);
        }
        vec.push_back(i); // 表示生產(chǎn)者生產(chǎn)的產(chǎn)品序號(hào)i
        std::cout << "producer生產(chǎn)產(chǎn)品:" << i << std::endl;

        /*
         * 容器為空,說(shuō)明需要生產(chǎn),生產(chǎn)完對(duì)其他線(xiàn)程進(jìn)行通訊
        生產(chǎn)者線(xiàn)程生產(chǎn)完產(chǎn)品,通知等待在cv條件變量上的消費(fèi)者線(xiàn)程,
        可以開(kāi)始消費(fèi)產(chǎn)品了,然后釋放鎖mtx
        */
        cv.notify_all();

        // 生產(chǎn)一個(gè)產(chǎn)品,睡眠100ms
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}
// 消費(fèi)者線(xiàn)程函數(shù)
void consumer()
{
    // 消費(fèi)者每消費(fèi)一個(gè),就通知生產(chǎn)者生產(chǎn)一個(gè)
    for (int i = 1; i <= 10; ++i)
    {
        // 獲取mtx互斥鎖資源
        std::unique_lock<std::mutex> lock(mtx);

        // 如果容器為空,代表還有沒(méi)有產(chǎn)品可消費(fèi),等待生產(chǎn)者生產(chǎn),再消費(fèi)
        while (vec.empty())
        {
            // 判斷容器為空,進(jìn)入等待條件變量的狀態(tài),釋放mtx鎖,
            // 讓生產(chǎn)者線(xiàn)程搶到鎖能夠去生產(chǎn)產(chǎn)品
            cv.wait(lock);//在等待過(guò)程中如果收到信息就會(huì)進(jìn)入阻塞狀態(tài),執(zhí)行下一步操作
        }
        int data = vec.back(); // 表示消費(fèi)者消費(fèi)的產(chǎn)品序號(hào)i
        vec.pop_back();
        std::cout << "consumer消費(fèi)產(chǎn)品:" << data << std::endl;

        /*
        消費(fèi)者消費(fèi)完產(chǎn)品,通知等待在cv條件變量上的生產(chǎn)者線(xiàn)程,
        可以開(kāi)始生產(chǎn)產(chǎn)品了,然后釋放鎖mtx
        */
        cv.notify_all();

        // 消費(fèi)一個(gè)產(chǎn)品,睡眠100ms
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}
int main()
{
    // 創(chuàng)建生產(chǎn)者和消費(fèi)者線(xiàn)程
    std::thread t1(producer);
    std::thread t2(consumer);

    // main主線(xiàn)程等待所有子線(xiàn)程執(zhí)行完
    t1.join();
    t2.join();

    return 0;
}

再談lock_guard和unique_lock

互斥鎖只有一個(gè)線(xiàn)程可以拿到,其他線(xiàn)程如果試圖拿到被別的線(xiàn)程占用的互斥鎖的時(shí)候會(huì)進(jìn)入阻塞狀態(tài)

std::lock_guard<std::mutex> lockGuard(mtx);不能用在函數(shù)參數(shù)傳遞或者返回過(guò)程中,只能用在簡(jiǎn)單的臨界區(qū)代碼段的互斥操作中

unique_lock可以使用在簡(jiǎn)單的臨界區(qū)代碼段的互斥操作中,也可以用在函數(shù)的調(diào)用過(guò)程中:

unque_lock<std::mutex> lck(mtx);
cv.wait(lck);//cv是condition_variable wait方法會(huì)先使線(xiàn)程進(jìn)入等待狀態(tài),然后調(diào)用lck.unlock()方法把mtx釋放掉。

cv.notify_all()是通知在cv上等待的線(xiàn)程條件成立了該干活了,收到通知的線(xiàn)程會(huì)先從等待狀態(tài)切換到阻塞狀態(tài),如果獲取到互斥鎖那么該線(xiàn)程就會(huì)繼續(xù)執(zhí)行。

基于CAS操作的atomic原子類(lèi)型

首先要包含atomic類(lèi)庫(kù)

一般在++等簡(jiǎn)單操作中使用無(wú)鎖操作(CAS)來(lái)實(shí)現(xiàn)

//原子整型,CAS操作保證給count自增自減的原子操作
std::atomic_int mycount(0);

//線(xiàn)程函數(shù)
void sumTask()
{
    //每個(gè)線(xiàn)程給count加1000次
    for (int i = 0; i < 1000; ++i)
    {
        mycount++;
    }
}

int main()
{
    //創(chuàng)建10個(gè)線(xiàn)程放在容器當(dāng)中
    std::vector<std::thread> vec;
    for (int i = 0; i < 10; ++i)
    {
        vec.push_back(std::thread(sumTask));
    }

    //等待線(xiàn)程執(zhí)行完成
    for (unsigned int i = 0; i < vec.size(); ++i)
    {
        vec[i].join();
    }

    //所有子線(xiàn)程運(yùn)行結(jié)束,count的結(jié)果每次運(yùn)行應(yīng)該都是
    std::cout << "count : " << mycount << std::endl;

    return 0;
}

網(wǎng)站題目:4.c++語(yǔ)言級(jí)別的多線(xiàn)程編程
文章來(lái)源:http://chinadenli.net/article12/dsoipdc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護(hù)、虛擬主機(jī)服務(wù)器托管、電子商務(wù)網(wǎng)站排名、網(wǎng)站收錄

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都app開(kāi)發(fā)公司