03 | this_thread名稱空間
在 C++11 中不僅添加了執行緒類,還添加了一個關於執行緒的名稱空間 std::this_thread,在這個名稱空間中提供了四個公共的成員函式,通過這些成員函式就可以對當前執行緒進行相關的操作了。
get_id()
呼叫名稱空間 std::this_thread 中的 get_id() 方法可以得到當前執行緒的執行緒 ID,函式原型如下:
thread::id get_id() noexcept;
sleep_for()
為了能夠實現併發處理,多個執行緒都是分時複用CPU時間片,快速的交替處理各個執行緒中的任務。因此多個執行緒之間需要爭搶CPU時間片,搶到了就執行,搶不到則無法執行
(因為預設所有的執行緒優先順序都相同,核心也會從中排程,不會出現某個執行緒永遠搶不到 CPU 時間片的情況)。
名稱空間 this_thread 中提供了一個休眠函式 sleep_for(),呼叫這個函式的執行緒會馬上從執行態變成阻塞態並在這種狀態下休眠一定的時長,因為阻塞態的執行緒已經讓出了 CPU 資源,程式碼也不會被執行,所以執行緒休眠過程中對 CPU 來說沒有任何負擔。這個函式是函式原型如下,引數需要指定一個休眠時長,是一個時間段.
template <class Rep, class Period>
void sleep_for (const chrono::duration<Rep,Period>& rel_time);
this_thread::sleep_for(chrono::seconds(1));//阻塞1s
sleep_until()
名稱空間 this_thread 中提供了另一個休眠函式 sleep_until(),和 sleep_for() 不同的是它的引數型別不一樣.
template <class Clock, class Duration>
void sleep_until (const chrono::time_point<Clock,Duration>& abs_time);
- sleep_until():指定執行緒阻塞到某一個指定的時間點 time_point型別,之後解除阻塞
- sleep_for():指定執行緒阻塞一定的時間長度 duration 型別,之後解除阻塞
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
void func()
{
for (int i = 0; i < 10; ++i)
{
// 獲取當前系統時間點
auto now = chrono::system_clock::now();
// 時間間隔為2s
chrono::seconds sec(2);
// 當前時間點之後休眠兩秒 **時間點加時間段還是時間點**
this_thread::sleep_until(now + sec);
cout << "子執行緒: " << this_thread::get_id() << ", i = " << i << endl;
}
}
int main()
{
thread t(func);
t.join();
}
yield()
使用這個函式的時候需要注意一點,執行緒呼叫了 yield () 之後會主動放棄 CPU 資源,但是這個變為就緒態的執行緒會馬上參與到下一輪 CPU 的搶奪戰中,不排除它能繼續搶到 CPU 時間片的情況,這是概率問題。
函式對應的示例程式如下:
#include <iostream>
#include <thread>
using namespace std;
void func()
{
for (int i = 0; i < 100000000000; ++i)
{
cout << "子執行緒: " << this_thread::get_id() << ", i = " << i << endl;
this_thread::yield();
}
}
int main()
{
thread t(func);
thread t1(func);
t.join();
t1.join();
}
在上面的程式中,執行 func() 中的 for 迴圈會佔用大量的時間,在極端情況下,如果當前執行緒佔用 CPU 資源不釋放就會導致其他執行緒中的任務無法被處理,或者該執行緒每次都能搶到 CPU 時間片,導致其他執行緒中的任務沒有機會被執行。解決方案就是每執行一次迴圈,讓該執行緒主動放棄 CPU 資源,重新和其他執行緒再次搶奪 CPU 時間片,如果其他執行緒搶到了 CPU 時間片就可以執行相應的任務了。
- std::this_thread::yield() 的目的是避免一個執行緒長時間佔用CPU資源,從而導致多執行緒處理效能下降
- std::this_thread::yield() 是讓當前執行緒主動放棄了當前自己搶到的CPU資源,但是在下一輪還會繼續搶