c++ multithread and lock--part 2

本文將對(duì)<thread>庫進(jìn)行詳細(xì)的介紹

class std::thread

std::thread是c++11開始提供的標(biāo)準(zhǔn)線程庫技掏,std::thread實(shí)質(zhì)上是對(duì)POSIX線程進(jìn)行了封裝幌羞,在不同平臺(tái)上對(duì)用戶是透明的恨诱。thread類主要提供了以下幾個(gè)方法:

  • join()蕾管,請(qǐng)參考前文前文http://www.reibang.com/p/19a8c88c6042齿拂。
  • detach()步鉴,請(qǐng)參考前文前文http://www.reibang.com/p/19a8c88c6042古劲。
  • get_id()斥赋,獲取線程id。每個(gè)線程創(chuàng)建時(shí)产艾,都會(huì)分配一個(gè)唯一的id作為線程的標(biāo)識(shí)疤剑。
  • swap(thread& t),交換兩個(gè)對(duì)象的對(duì)象,使用方式如下:
#include <iostream>
#include <thread>
#define TEST(X)        \
  void test##X() {   \
  }
TEST(1)
TEST(2)
int main() {
   std::thread t1(test1);
   std::thread t2(test2);
   std::cout << " the id of t1 = " << t1.get_id() << std::endl;
   std::cout << " the id of t2 = " << t2.get_id() << std::endl;
   std::cout << " ------------------AFTER SWAP---------------" << std::endl;
   t1.swap(t2);
   std::cout << " the id of t1 = " << t1.get_id() << std::endl;
   std::cout << " the id of t2 = " << t2.get_id() << std::endl;

   return 0;
}

運(yùn)行結(jié)果:

 the id of t1 = 0x70000efc3000
 the id of t2 = 0x70000f046000
 ------------------AFTER SWAP---------------
 the id of t1 = 0x70000f046000
 the id of t2 = 0x70000efc3000
  • joinable()闷堡,用于判斷線程對(duì)象是否是可join的隘膘,方法的返回值是bool類型的。當(dāng)一個(gè)線程處于運(yùn)行狀態(tài)那么它是可join的杠览,一個(gè)線程在以下三種情況下是不可join的:
    (1)由默認(rèn)構(gòu)造函數(shù)構(gòu)造
    (2)通過移動(dòng)構(gòu)造
    (3)已經(jīng)調(diào)用了join()或detach()方法
    使用代碼如下:
#include <iostream>
#include <thread>

#define TEST(X)        \
   void test##X() {   \
   }

TEST(2)
TEST(3)
TEST(4)

class thread_wrap : public std::thread {
public:
    thread_wrap(std::function<void()> callback) : std::thread(callback){
    }
    thread_wrap() : std::thread(){
    }
    std::string joinable_wrap() {
        std::string result;
        if(joinable()) {
            return "true";
        }
        return "false";
    }
};

int main() {
    // thread_wrap t1();
    thread_wrap t2(test2);
    t2.join();
    thread_wrap t3(test3);
    t3.detach();
    thread_wrap t4(test4);

    // std::cout << " the joinable of t1 = " << t1.joinable_wrap() << std::endl;
    std::cout << " the joinable of t2 = " << t2.joinable_wrap() << std::endl;
    std::cout << " the joinable of t3 = " << t3.joinable_wrap() << std::endl;
    std::cout << " the joinable of t4 = " << t4.joinable_wrap() << std::endl;

    return 0;
}

運(yùn)行結(jié)果:

 the joinable of t2 = false
 the joinable of t3 = false
 the joinable of t4 = true
  • native_handle(),持有的pthread對(duì)象弯菊。
  • hardware_concurrency(),用于查詢機(jī)器上有多少個(gè)CPU,返回值是unsigned類型踱阿。

namespace std::this_thread

類std::thread的所有輔助函數(shù)均位于this_thread的命名空間中管钳,如:

namespace this_thread{
  thread::id get_id() _NOEXCEPT;
  inline void yield()  _NOEXCEPT;
  template<class _Rep, class _Period> inline 
  void sleep_for(const chrono::duration<_Rep, _Period>& __d);
  template<class _Clock, class _Duration> inline
  void sleep_until(const chrono::time_point<_Clock, _Duration>& __t);
}

yield(),當(dāng)前線程讓出cpu資源钦铁,提供提示給實(shí)現(xiàn),以重新調(diào)度線程的執(zhí)行才漆,允許其他線程運(yùn)行牛曹。在當(dāng)前線程執(zhí)行過程中某一必須條件暫時(shí)還不滿足時(shí),使用 std::this_thread::yield() , 將其未使用完的CPU資源讓出給其他線程使用, 等到其他線程用完后, 再和其他線程一起競(jìng)爭使用醇滥,這樣可以避免cpu資源的無效占用而影響程序運(yùn)行性能黎比。

#include <iostream>
#include <chrono>
#include <thread>
 
void test_sleep(std::chrono::microseconds us)
{
    auto start = std::chrono::high_resolution_clock::now();
    auto end = start + us;
    do {
        std::this_thread::yield();
    } while (std::chrono::high_resolution_clock::now() < end);
}
 
int main()
{
    auto start = std::chrono::high_resolution_clock::now();
 
    test_sleep(std::chrono::microseconds(100));
 
    auto elapsed = std::chrono::high_resolution_clock::now() - start;
    std::cout << "waited for "
              << std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count()
              << " microseconds\n";
}

sleep_for(), 將當(dāng)前線程休眠一段時(shí)間,不再與其他線程爭搶cpu資源鸳玩,但是并不讓出當(dāng)前占用的cpu資源焰手。

#include <iostream>       // std::cout, std::endl
#include <thread>         // std::this_thread::sleep_for
#include <chrono>         // std::chrono::seconds
 
int main() 
{
  std::cout << "countdown:\n";
  for (int i=10; i>0; --i) {
    std::cout << i << std::endl;
    std::this_thread::sleep_for (std::chrono::seconds(1));
  }
  std::cout << "Lift off!\n";

  return 0;
}

sleep_until(),將當(dāng)前線程阻塞至某一時(shí)間點(diǎn)之后。在這一過程中不再與其他線程爭搶cpu資源怀喉,但是并不讓出當(dāng)前占用的cpu資源。

 #include <iostream>       // std::cout
#include <iomanip>        // std::put_time
#include <thread>         // std::this_thread::sleep_until
#include <chrono>         // std::chrono::system_clock
#include <ctime>          // std::time_t, std::tm, std::localtime, std::mktime

int main() 
{
  using std::chrono::system_clock;
  std::time_t tt = system_clock::to_time_t (system_clock::now());
  struct std::tm * ptm = std::localtime(&tt);
  std::cout << "Current time: " << std::put_time(ptm,"%X") << '\n';

  std::cout << "Waiting for the next minute to begin...\n";
  ++ptm->tm_min; ptm->tm_sec=0;
  std::this_thread::sleep_until (system_clock::from_time_t (mktime(ptm)));

  std::cout << std::put_time(ptm,"%X") << " reached!\n";
  return 0;
}

參考鏈接:
http://www.cplusplus.com/reference/multithreading/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末船响,一起剝皮案震驚了整個(gè)濱河市躬拢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌见间,老刑警劉巖聊闯,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異米诉,居然都是意外死亡菱蔬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門史侣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拴泌,“玉大人,你說我怎么就攤上這事惊橱◎礁” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵税朴,是天一觀的道長回季。 經(jīng)常有香客問我,道長正林,這世上最難降的妖魔是什么泡一? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮觅廓,結(jié)果婚禮上鼻忠,老公的妹妹穿的比我還像新娘。我一直安慰自己杈绸,他們只是感情好粥烁,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布贤笆。 她就那樣靜靜地躺著,像睡著了一般讨阻。 火紅的嫁衣襯著肌膚如雪芥永。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天钝吮,我揣著相機(jī)與錄音埋涧,去河邊找鬼。 笑死奇瘦,一個(gè)胖子當(dāng)著我的面吹牛棘催,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播耳标,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼醇坝,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了次坡?” 一聲冷哼從身側(cè)響起呼猪,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎砸琅,沒想到半個(gè)月后宋距,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡症脂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年谚赎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诱篷。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡壶唤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出棕所,到底是詐尸還是另有隱情视粮,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布橙凳,位于F島的核電站蕾殴,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏岛啸。R本人自食惡果不足惜钓觉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坚踩。 院中可真熱鬧荡灾,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至荧缘,卻和暖如春皆警,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背截粗。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國打工信姓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人绸罗。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓意推,卻偏偏與公主長得像,于是被迫代替她去往敵國和親珊蟀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子菊值,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容