目录
- 1 概述
- 2 使用实例
- 3 接口使用
- 3.1 construct
- 3.2 assigns
- 3.3 get_id
- 3.4 joinable
- 3.5 join
- 3.6 detach
- 3.7 swap
- 3.8 hardware_concurrency
1 概述
Thread类来表示执行的各个线程。
执行线程是指可以在多线程环境中与其他此类序列同时执行的指令序列,同时共享相同的地址空间。
初始化的线程对象表示执行的活动线程;这样的线程对象是可连接(joinable)的,并且具有唯一的线程id。
默认构造(未初始化)的线程对象是不可连接的,其线程id对于所有不可连接线程都是通用的。
如果移动赋值,或者对可连接线程调用join或detach,则可连接(joinable)线程将变为不可连接线程。
其类图如下:
2 使用实例
void function_a()
{
std::cerr << "this is in funciton_a" << std::endl;
}
void function_b(int n)
{
for(int i = 0; i < n; i++)
std::cerr << "this is in funciton_b" << std::endl;
}
struct C
{
void function(int n)
{
for(int i = 0; i < n; i++)
std::cerr << "this is in C::funciton" << std::endl;
}
};
void ThreadSuite::construct()
{
C func;
std::thread a;
std::thread b(function_a);
std::thread c(function_b, 2);
std::thread d(&C::function, std::ref(func), 2);
std::thread e = std::thread(function_b, 3);
TEST_ASSERT_EQUALS(false, a.joinable())
TEST_ASSERT_EQUALS(true, b.joinable())
TEST_ASSERT_EQUALS(true, c.joinable())
TEST_ASSERT_EQUALS(true, d.joinable())
TEST_ASSERT_EQUALS(true, e.joinable())
b.join();
c.join();
d.join();
e.join();
}
3 接口使用
3.1 construct
void ThreadSuite::construct()
{
C func;
std::thread a;
std::thread b(function_a);
std::thread c(function_b, 2);
std::thread d(&C::function, std::ref(func), 2);
std::thread e = std::thread(function_b, 3);
TEST_ASSERT_EQUALS(false, a.joinable())
TEST_ASSERT_EQUALS(true, b.joinable())
TEST_ASSERT_EQUALS(true, c.joinable())
TEST_ASSERT_EQUALS(true, d.joinable())
TEST_ASSERT_EQUALS(true, e.joinable())
b.join();
c.join();
d.join();
e.join();
}
3.2 assigns
void ThreadSuite::assigns()
{
std::thread a(function_a);
std::thread b;
TEST_ASSERT_EQUALS(true, a.joinable())
TEST_ASSERT_EQUALS(false, b.joinable())
b = std::move(a);
TEST_ASSERT_EQUALS(false, a.joinable())
TEST_ASSERT_EQUALS(true, b.joinable())
b.join();
}
说明:
- 移动赋值后,线程由可连接变成不可连接了。
3.3 get_id
struct FunctionForGetId
{
std::thread::id id;
void function()
{
id = std::this_thread::get_id();
}
};
void ThreadSuite::get_id()
{
FunctionForGetId fun;
std::thread a;
std::thread b;
std::thread c(&FunctionForGetId::function, std::ref(fun));
std::thread::id id = c.get_id();
TEST_ASSERT_EQUALS(true, a.get_id() == b.get_id())
c.join();
TEST_ASSERT_EQUALS(true, (fun.id == id))
TEST_ASSERT_EQUALS(true, (fun.id != c.get_id()))
}
说明:
- 未初始化的线程其id是相同的。
- 线程join前后线程id是不同的。
3.4 joinable
void ThreadSuite::joinable()
{
std::thread a(function_a);
std::thread b;
TEST_ASSERT_EQUALS(true, a.joinable())
TEST_ASSERT_EQUALS(false, b.joinable())
a.join();
TEST_ASSERT_EQUALS(false, a.joinable())
}
说明:
- 线程join后线程变为不可连接了
3.5 join
void ThreadSuite::join()
{
std::thread a(function_a);
std::thread b;
TEST_ASSERT_EQUALS(true, a.joinable())
TEST_ASSERT_EQUALS(false, b.joinable())
a.join();
if(b.joinable())
b.join();
TEST_ASSERT_EQUALS(false, a.joinable())
}
说明:
- 对不可连接线程调用join,将导致不可预料结果。
- 线程join后线程变为不可连接了
3.6 detach
void ThreadSuite::detach()
{
std::thread a(function_a);
TEST_ASSERT_EQUALS(true, a.joinable())
a.detach();
TEST_ASSERT_EQUALS(false, a.joinable())
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
说明:
- 线程detach后线程变为不可连接了
3.7 swap
void ThreadSuite::swap()
{
std::thread a(function_a);
std::thread b;
TEST_ASSERT_EQUALS(true, a.joinable())
TEST_ASSERT_EQUALS(false, b.joinable())
a.swap(b);
TEST_ASSERT_EQUALS(false, a.joinable())
TEST_ASSERT_EQUALS(true, b.joinable())
b.join();
}
3.8 hardware_concurrency
void ThreadSuite::hardware_concurrency()
{
std::cerr << "\n\nhardware_concurrency:" << std::thread::hardware_concurrency() << std::endl;
TEST_ASSERT_EQUALS(true, std::thread::hardware_concurrency() > 0)
}
说明:
- 该函数返回硬件并发性,我的机器返回12,正好是CPU的逻辑核数。