线程标识
std::thread::id唯一标识线程,支持比较,可作为容器键,默认值表示无线程。
线程标识
线程标识
获取线程标识的两种方式
通过 std::thread
对象获取
1
2
std::thread t([]{ /* do something */ });
std::thread::id id = t.get_id();
如果
std::thread
没有绑定线程,get_id()
返回默认构造的std::thread::id
,代表“无线程”。“没有绑定线程”的情况举例:
std::thread
对象刚被默认构造,没启动线程:1
std::thread t; // 空线程对象,没有启动任何线程
线程执行完毕且被
join()
后,线程对象与线程解绑:1 2
std::thread t([]{ /*...*/ }); t.join(); // 线程执行完毕,t 不再关联任何线程
线程对象被移动后,原对象不再关联线程:
1 2 3
std::thread t1([]{ /*...*/ }); std::thread t2 = std::move(t1); // 现在 t1 是空的,没有绑定线程,t2 关联线程
std::thread::id()
是默认构造的线程ID,和t.get_id()
返回值相等,说明t
是空的1 2 3 4 5 6
std::thread t; // 默认构造,没有启动线程 auto id = t.get_id(); if (id == std::thread::id()) { std::cout << "t没有关联任何线程\n"; }
通过当前线程调用
1
std::thread::id id = std::this_thread::get_id(); // 需要包含 <thread>
线程标识的比较与用法
std::thread::id
可拷贝、赋值、比较(==、!=、<、> 等),可以用于排序。也可以用于作为 有序/无序容器(如
std::map
,std::unordered_map
) 的键:1 2
std::unordered_map<std::thread::id, ThreadData> threadDataMap; threadDataMap[std::this_thread::get_id()] = someData;
标准库提供
std::hash<std::thread::id>
,使其可用于哈希容器。
典型应用场景
示例 1:主线程做不同操作
某些并行任务中,主线程可能要处理与其他线程不同的逻辑,可以通过线程 ID 判断:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
std::thread::id master_thread;
void some_core_part_of_algorithm() {
if (std::this_thread::get_id() == master_thread) {
do_master_thread_work(); // 主线程专属工作
}
do_common_work(); // 所有线程通用任务
}
int main() {
master_thread = std::this_thread::get_id();
std::thread t1(some_core_part_of_algorithm);
std::thread t2(some_core_part_of_algorithm);
some_core_part_of_algorithm(); // 主线程执行
t1.join();
t2.join();
}
示例 2:线程 ID 作为权限标识
线程 ID 可以存入结构体,用于判断某个操作是否“被允许”或“被要求”:
1
2
3
4
5
6
7
8
9
10
11
12
13
struct ThreadGuard {
std::thread::id owner;
ThreadGuard() : owner(std::this_thread::get_id()) {}
void do_work() {
if (std::this_thread::get_id() == owner) {
std::cout << "Allowed to work\n";
} else {
std::cout << "Not allowed\n";
}
}
};
示例 3:线程 ID 作为线程信息索引键
1
2
3
4
5
6
std::map<std::thread::id, std::string> threadNames;
void threadFunction(const std::string& name) {
threadNames[std::this_thread::get_id()] = name;
std::cout << "Hello from " << threadNames[std::this_thread::get_id()] << "\n";
}
线程 ID 的输出
可将线程 ID 输出到标准流(如 std::cout
),以便调试:
1
std::cout << "Current thread ID: " << std::this_thread::get_id() << "\n";
注意:线程 ID 的具体输出形式是 实现相关的,但 相同线程必须输出相同的 ID。
总结
特性 | 说明 |
---|---|
类型 | std::thread::id |
默认值 | std::thread::id() 表示“无线程” |
获取方式 | t.get_id() / std::this_thread::get_id() |
可用于比较/排序 | 支持 < , == , != 等运算符 |
可用于容器键 | std::map , std::unordered_map 等 |
常见用途 | 判断线程身份、区分主从线程、存储线程信息等 |
可输出 | std::cout << std::this_thread::get_id() |
本文由作者按照 CC BY 4.0 进行授权