C++11多線程


參考:

http://www.oschina.net/translate/cplusplus-11-threading-make-your-multitasking-life

http://blog.jobbole.com/44409/

線程

類std::thread代表一個可執行線程,使用時必須包含頭文件<thread>。std::thread可以和普通函數,匿名函數和仿函數(一個實現了operator()函數的類)一同使用。另外,它允許向線程函數傳遞任意數量的參數。

#include <thread>

void func()
{
   // do some work
}

int main()
{
   std::thread t(func);
   t.join();

   return 0;
}

上例中,t 是一個線程對象,函數func()運行於該線程中。對join()函數的調用將使調用線程(本例是指主線程)一直處於阻塞狀態,直到正在執行的線程t執行結束。如果線程函數返回某個值,該值也將被忽略。不過,該函數可以接收任意數量的參數。

 1 void func(int i, double d, const std::string& s)
 2 {
 3     std::cout << i << ", " << d << ", " << s << std::endl;
 4 }
 5  
 6 int main()
 7 {
 8    std::thread t(func, 1, 12.50, "sample");
 9    t.join();
10  
11    return 0;
12 }

盡管可以向線程函數傳遞任意數量的參數,但是所有的參數應當按值傳遞。如果需要將參數按引用傳遞,那要向下例所示那樣,必須將參數用std::ref 或者std::cref進行封裝。

void func(int& a)
{
   a++;
}
 
int main()
{
   int a = 42;
   std::thread t(func, std::ref(a));
   t.join();
 
   std::cout << a << std::endl;
 
   return 0;
}

該程序打印結果為43,但是如果不用std::ref把參數a進行封裝的話,輸出結果將為42

Detach: 允許執行該方法的線程脫離其線程對象而繼續獨立執行。脫離后的線程不再是可結合線程(你不能等待它們執行結束)。

int main()
{
    std::thread t(funct);
    t.detach();
 
    return 0;
}

互斥Mutex

C++ 11的<mutex>頭文件里包含了四種不同的互斥量:

  • Mutex: 提供了核心函數 lock() 和 unlock(),以及非阻塞方法的try_lock()方法,一旦互斥量不可用,該方法會立即返回。
  • Recursive_mutex:允許在同一個線程中對一個互斥量的多次請求。
  • Timed_mutex:同上面的mutex類似,但它還有另外兩個方法 try_lock_for() 和 try_lock_until(),分別用於在某個時間段里或者某個時刻到達之間獲取該互斥量。
  • Recursive_timed_mutex: 結合了timed_mutex 和recuseive_mutex的使用。

std::mutex與win32的臨界區(cirtical section)很類似。lock()如同EnterCriticalSection,unlock如同LeaveCriticalSection,try_lock則像TryEnterCriticalSection。

std::mutex m;
int j = 0;
void foo()
{
    m.lock();        // 進入臨界區域
    j++;
    m.unlock();      // 離開
}
void func()
{
    std::thread t1(foo);
    std::thread t2(foo);
    t1.join();
    t2.join();
    // j = 2;
}

如上,你在lock一個 std::mutex 對象之后必須解鎖(unlock)。如果你已經對其加鎖,你不能再次lock。這與win32 不同,如果你已經在臨界區(critical section)里,再次 EnterCriticalSection不會失敗,但是會增加一個計數。

嗨,不要走開哦。前面提到不能對std::mutex重復lock。這里有std::recursive_mutex(誰發明的這名字),它的行為則與臨界區(critical section)相似,可以重復lock。

std::recursive_mutex m;
void foo()
{
    m.lock();
    m.lock(); // now valid
    j++;
    m.unlock();
    m.unlock(); // don't forget!
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM