天天看點

C++11中的多線程使用

導言:随着計算機硬體條件的提升,軟體的設計與開發更多的看重其執行速度,而采用多線程并發的執行一些操作對提升效率至關重要。

C++11的出現,給了使用者很大的友善,摒棄了原有的windows線程設計函數,而采用了std::thread來設計線程函數,隻要包含頭檔案<thread.h>就行。

1.1 建立線程

std::thread t(func); //func-線程函數名, t-線程名,将線程函數放到線程t中執行。

t.join();//線程執行開始

注意:線程的開始執行方法又兩種,join(),或者detach().

join()方法: join()函數将阻塞線程直到線程函數結束

detach()方法: detach()函數将線程和線程對象分離,分離後無法再和線程函數聯系,可通過回調傳回其執行結果。
           

1.2 建立線程+lamada表達式

1.2.1 lamada的格式:[ 捕獲值方式](形參){函數體}

   捕獲值方式有以下幾種:

      [ &]:引用捕獲,直接引用線程外部函數的值,缺點是:在并發執行過程中,很可能線程所在的類已經析構,而線程函數還在執行,這樣将導緻線程函數引用的值不存在,而導緻崩潰。

      [ =]:拷貝方式捕獲,拷貝一份外部函數中的變量值,跟随線程函數執行,這種方式較為穩妥

      [ bar]:拷貝外部變量bar的副本供線程函數使用

       [ this]:捕獲目前類中的this指針,讓lamada表達式擁有和目前類成員函數同樣的通路權限。即:使用

目前類的成員函數和成員變量。

1.2.2 互斥量

       線上程的運作過程中,多個線程競争同一資源的情況下,需要用到互斥鎖來防止資源被破壞

std::mutex m_lock;

     例如

void func()

{

     m_lock.lock();//加鎖

     funcrate();

     m_lock.lock();//解鎖

}
           

     還有一個lock_gurd,不需要進行加鎖和解鎖的頻繁操作

void func()

{

    std::lock_guard<std::mutex> locker(m_lock);//加鎖,自動解鎖

    funcrate();

}
           

         遞歸互斥量:避免一個線程多次擷取互斥量時死鎖

         例如:std::recursive_mutex m_mutex;

1.2.3 條件變量(另一種線程同步的方法,它将阻塞一個或多個線程直到收到另外一個線程)

           condition_variable, 配合std::unique_lock<std::mutex> 進行wait操作

           condition_variable_any, 可配合任意帶有lock、unlock語義的mutex 搭配使用,使用靈活

1.4 lamada+std::thread一起使用

void Func(const std::wstring& file,IAddFileCallback* pCallback)

{

   int nNum=10;

   std::thread t([=]()

     {

           shortfunc( file);

            nNum++;

          if (pCallback)
          {
            wstring strLocalCachePath = L"";
            if (bResult)
                strLocalCachePath = m_strLoacalParentPath + strRelativePath;
            
            pCallback->OnFileCallback(strRelativePath, strLocalCachePath, bResult);
            }

       }

   )

    t.detach();

}
           

std::ref(num);//直接拷貝對象,不需要引用

1.5 線程異步擷取傳回值

可以使用是std::future來擷取線程傳回值

reterance:https://www.cnblogs.com/haippy/p/3280643.html

例如:

bool do_check_prime(int x) // 為了展現效果, 該函數故意沒有優化.
{
    for (int i = 2; i < x; ++i)
        if (x % i == 0)
            return false;
    return true;
}
           

int mian()

{

std::future < bool > fut = std::async(do_check_prime, 194232491);

    std::cout << "Checking...\n";
    fut.wait();//等待。。。

    std::cout << "\n194232491 ";
    if (fut.get()) // guaranteed to be ready (and not block) after wait returns
        std::cout << "is prime.\n";
    else
        std::cout << "is not prime.\n";

    return 0;
}
           

繼續閱讀