c++ multithread and lock--part 2
2019-11-17 本文已影响0人
前进中的奋斗猿
本文将对<thread>库进行详细的介绍
class std::thread
std::thread是c++11开始提供的标准线程库,std::thread实质上是对POSIX线程进行了封装,在不同平台上对用户是透明的。thread类主要提供了以下几个方法:
- join(),请参考前文前文https://www.jianshu.com/p/19a8c88c6042。
- detach(),请参考前文前文https://www.jianshu.com/p/19a8c88c6042。
- get_id(),获取线程id。每个线程创建时,都会分配一个唯一的id作为线程的标识。
- swap(thread& t),交换两个对象的对象,使用方式如下:
#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;
}
运行结果:
the id of t1 = 0x70000efc3000
the id of t2 = 0x70000f046000
------------------AFTER SWAP---------------
the id of t1 = 0x70000f046000
the id of t2 = 0x70000efc3000
-
joinable(),用于判断线程对象是否是可join的,方法的返回值是bool类型的。当一个线程处于运行状态那么它是可join的,一个线程在以下三种情况下是不可join的:
(1)由默认构造函数构造
(2)通过移动构造
(3)已经调用了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;
}
运行结果:
the joinable of t2 = false
the joinable of t3 = false
the joinable of t4 = true
- native_handle(),持有的pthread对象。
- hardware_concurrency(),用于查询机器上有多少个CPU,返回值是unsigned类型。
namespace std::this_thread
类std::thread的所有辅助函数均位于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(),当前线程让出cpu资源,提供提示给实现,以重新调度线程的执行,允许其他线程运行。在当前线程执行过程中某一必须条件暂时还不满足时,使用 std::this_thread::yield() , 将其未使用完的CPU资源让出给其他线程使用, 等到其他线程用完后, 再和其他线程一起竞争使用,这样可以避免cpu资源的无效占用而影响程序运行性能。
#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(), 将当前线程休眠一段时间,不再与其他线程争抢cpu资源,但是并不让出当前占用的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(),将当前线程阻塞至某一时间点之后。在这一过程中不再与其他线程争抢cpu资源,但是并不让出当前占用的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;
}