最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c++11新特性多線程操作實戰(zhàn)

 更新時間:2020年09月27日 10:54:31   作者:鬼谷子com  
這篇文章主要介紹了c++11新特性多線程操作實戰(zhàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

c++11多線程操作

線程

thread

int main()
{
  thread t1(Test1);
  t1.join();
  thread t2(Test2);
  t2.join();
  thread t3 = t1;
  thread t4(t1);
  thread t5 = std::move(t1);
  thread t6(std::move(t1));
  return 0;
}

t3,t4創(chuàng)建失敗,因為thread的拷貝構(gòu)造和賦值運算符重載的原型是:

thread(const thread&) = delete;
thread& operator=(const thread&) = delete;

被禁用了,但是t5, t6線程是創(chuàng)建成功的。std::move把t1轉(zhuǎn)換為右值,調(diào)用的是函數(shù)原型為thread& operator=(thread&& _Other) noexceptthread(thread&& _Other) noexcept。

當線程對象t1被移動拷貝和移動賦值給t5和t6的時候,t1就失去了線程控制權(quán),也就是一個線程只能同時被一個線程對象所控制。最直觀的是t1.joinable()返回值為false,joinable()函數(shù)后面介紹。

使用類成員函數(shù)作為線程參數(shù):

class Task
{
public:
  Task(){}
  void Task1() {}
  void Task2() {}
private:
};

int main()
{
  Task task;
  thread t3(&Task::Task1, &task);
  t3.join();
  return 0;
}

關(guān)鍵點是要創(chuàng)建一個類對象,并作為第二個參數(shù)傳入thread()線程的構(gòu)造函數(shù)中去。

管理當前線程的函數(shù)

yield

此函數(shù)的準確性為依賴于實現(xiàn),特別是使用中的 OS 調(diào)度器機制和系統(tǒng)狀態(tài)。例如,先進先出實時調(diào)度器( Linux 的 SCHED_FIFO )將懸掛當前線程并將它放到準備運行的同優(yōu)先級線程的隊列尾(而若無其他線程在同優(yōu)先級,則 yield 無效果)。

#include <iostream>
#include <chrono>
#include <thread>
 
// 建議其他線程運行一小段時間的“忙睡眠”
void little_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();
 
  little_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";
}

get_id

這個函數(shù)不用過多介紹了,就是用來獲取當前線程id的,用來標識線程的身份。

std::thread::id this_id = std::this_thread::get_id();

sleep_for

位于this_thread命名空間下,msvc下支持兩種時間參數(shù)。

std::this_thread::sleep_for(2s);
std::this_thread::sleep_for(std::chrono::seconds(1));

sleep_untile

參數(shù)構(gòu)建起來挺麻煩的,一般場景下要求線程睡眠的就用sleep_for就行了

using std::chrono::system_clock;
time_t tt = system_clock::to_time_t(system_clock::now());
struct std::tm *ptm = localtime(&tt);
 std::this_thread::sleep_until(system_clock::from_time_t(mktime(ptm)));

互斥

mutex

對于互斥量看到一個很好的比喻:

單位上有一臺打印機(共享數(shù)據(jù)a),你要用打印機(線程1要操作數(shù)據(jù)a),同事老王也要用打印機(線程2也要操作數(shù)據(jù)a),但是打印機同一時間只能給一個人用,此時,規(guī)定不管是誰,在用打印機之前都要向領(lǐng)導申請許可證(lock),用完后再向領(lǐng)導歸還許可證(unlock),許可證總共只有一個,沒有許可證的人就等著在用打印機的同事用完后才能申請許可證(阻塞,線程1lock互斥量后其他線程就無法lock,只能等線程1unlock后,其他線程才能lock),那么,這個許可證就是互斥量?;コ饬勘WC了使用打印機這一過程不被打斷。

代碼示例:

mutex mtx;

int gNum = 0;
void Test1()
{
  mtx.lock();
  for(int n = 0; n < 5; ++n)
    gNum++;
  mtx.unlock();
}

void Test2()
{
  std::cout << "gNum = " << gNum << std::endl;
}

int main()
{
  thread t1(Test1);
  t1.join();
  thread t2(Test2);
  t2.join();
  return 0;
}

join()表示主線程等待子線程結(jié)束再繼續(xù)執(zhí)行,如果我們的期望是打印循環(huán)自增之后的gNum的值,那t1.join()就放在t2創(chuàng)建之前調(diào)用。因為t2的創(chuàng)建就標志著t2線程創(chuàng)建好然后開始執(zhí)行了。

通常mutex不單獨使用,因為lock和unlock必須配套使用,如果忘記unlock很可能造成死鎖,即使unlock寫了,但是如果在執(zhí)行之前程序捕獲到異常,也還是一樣會死鎖。如何解決使用mutex造成的死鎖問題呢?下面介紹unique_gard和lock_guard的時候詳細說明。

timed_mutex
提供互斥設(shè)施,實現(xiàn)有時限鎖定

recursive_mutex
提供能被同一線程遞歸鎖定的互斥設(shè)施

recursive_timed_mutex
提供能被同一線程遞歸鎖定的互斥設(shè)施,并實現(xiàn)有時限鎖定

通用互斥管理

lock_guard

void Test1()
{
  std::lock_guard<std::mutex> lg(mtx);
  for(int n = 0; n < 5; ++n)
  {
    gNum++;
    std::cout << "gNum = " << gNum << std::endl;
  }
}
int main()
{
  thread t1(Test1);
  thread t2(Test1);
  t1.join();
  t2.join();
  return 0;
}

lock_guard相當于利用RAII機制(“資源獲取就是初始化”)把mutex封裝了一下,在構(gòu)造中l(wèi)ock,在析構(gòu)中unlock。避免了中間過程出現(xiàn)異常導致的mutex不能夠正常unlock.

  • scoped_lock(c++17)
  • unique_lock
  • defer_lock_t
  • try_to_lock_t
  • adopt_lock_t
  • defer_lock
  • try_to_lock
  • adopt_lock

通用鎖算法

  • try_lock
  • lock

單次調(diào)用

  • once_flag
  • call_once

條件變量

  • condition_variable
  • condition_variable_any
  • notify_all_at_thread_exit
  • cv_status

Future

  • promise
  • packaged_task
  • future
  • shared_future
  • async
  • launch
  • future_status
  • Future錯誤
    • future_error
    • future_category
    • future_errc

到此這篇關(guān)于c++11新特性多線程操作實戰(zhàn)的文章就介紹到這了,更多相關(guān)c++11 多線程操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

六枝特区| 嘉禾县| 云浮市| 岑巩县| 龙岩市| 广河县| 辰溪县| 三穗县| 文水县| 永安市| 宁都县| 孝昌县| 手游| 黎城县| 方城县| 衡水市| 忻州市| 阿尔山市| 宝山区| 饶阳县| 玉龙| 江永县| 胶州市| 凌源市| 台东县| 乌拉特前旗| 南丹县| 潜山县| 额敏县| 鲁山县| 天津市| 梧州市| 磴口县| 江达县| 土默特左旗| 修武县| 高陵县| 桐庐县| 若尔盖县| 新巴尔虎右旗| 通道|