本文將對(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;
}