跳转到内容

C++ 线程标识

来自代码酷

C++线程标识是C++多线程编程中用于唯一识别线程的核心概念。每个线程在创建时都会被分配一个唯一的标识符,开发者可以通过这些标识符管理、调试或区分不同线程的执行逻辑。本文将详细介绍C++标准库中与线程标识相关的工具及其实际应用。

概述[编辑 | 编辑源代码]

在C++11及更高版本中,线程标识通过std::thread::id类型表示。它是一个轻量级的、可比较的类,用于唯一标识线程。主线程和子线程的标识不同,且销毁的线程标识可能被系统复用。

关键特性[编辑 | 编辑源代码]

  • 唯一性:每个活跃线程的std::thread::id唯一。
  • 可比较性:支持==!=等操作符,用于判断线程是否相同。
  • 哈希支持:可用于STL无序容器(如std::unordered_map)。

获取线程标识[编辑 | 编辑源代码]

以下方法可获取线程标识:

当前线程标识[编辑 | 编辑源代码]

使用std::this_thread::get_id()获取当前线程的标识:

  
#include <iostream>  
#include <thread>  

int main() {  
    std::cout << "Main thread ID: " << std::this_thread::get_id() << '\n';  
}

输出示例

  
Main thread ID: 140737345955648  

线程对象的标识[编辑 | 编辑源代码]

通过std::thread对象的成员函数get_id()获取:

  
#include <iostream>  
#include <thread>  

void foo() {  
    std::cout << "Thread ID: " << std::this_thread::get_id() << '\n';  
}  

int main() {  
    std::thread t(foo);  
    std::cout << "Main thread ID: " << std::this_thread::get_id() << '\n';  
    std::cout << "Child thread ID: " << t.get_id() << '\n';  
    t.join();  
}

输出示例

  
Main thread ID: 140737345955648  
Child thread ID: 140737337628416  
Thread ID: 140737337628416  

线程标识的实际应用[编辑 | 编辑源代码]

调试与日志[编辑 | 编辑源代码]

在多线程程序中,通过标识区分日志来源:

  
#include <iostream>  
#include <thread>  
#include <vector>  

void worker(int id) {  
    std::cout << "Thread " << id << " (ID: " << std::this_thread::get_id() << ") working\n";  
}  

int main() {  
    std::vector<std::thread> threads;  
    for (int i = 0; i < 3; ++i) {  
        threads.emplace_back(worker, i);  
    }  
    for (auto& t : threads) {  
        t.join();  
    }  
}

输出示例

  
Thread 0 (ID: 140737337628416) working  
Thread 1 (ID: 140737329235712) working  
Thread 2 (ID: 140737320843008) working  

线程特定存储[编辑 | 编辑源代码]

结合std::unordered_map实现线程本地数据管理:

  
#include <iostream>  
#include <thread>  
#include <unordered_map>  
#include <mutex>  

std::unordered_map<std::thread::id, int> thread_data;  
std::mutex mtx;  

void add_data(int value) {  
    std::lock_guard<std::mutex> lock(mtx);  
    thread_data[std::this_thread::get_id()] = value;  
}  

int main() {  
    std::thread t1(add_data, 10), t2(add_data, 20);  
    t1.join();  
    t2.join();  

    for (const auto& pair : thread_data) {  
        std::cout << "Thread " << pair.first << ": " << pair.second << '\n';  
    }  
}

输出示例

  
Thread 140737329235712: 20  
Thread 140737337628416: 10  

线程标识的比较与哈希[编辑 | 编辑源代码]

std::thread::id支持比较和哈希操作,适用于条件分支和容器存储:

  
#include <iostream>  
#include <thread>  
#include <unordered_set>  

int main() {  
    std::thread::id main_id = std::this_thread::get_id();  
    std::thread t([]{});  
    std::thread::id child_id = t.get_id();  

    std::cout << "Is main thread? " << (main_id == std::this_thread::get_id()) << '\n';  
    std::cout << "Is child thread? " << (child_id == std::this_thread::get_id()) << '\n';  

    std::unordered_set<std::thread::id> id_set;  
    id_set.insert(main_id);  
    id_set.insert(child_id);  
    std::cout << "Unique IDs stored: " << id_set.size() << '\n';  

    t.join();  
}

输出示例

  
Is main thread? 1  
Is child thread? 0  
Unique IDs stored: 2  

高级主题:线程标识的内部表示[编辑 | 编辑源代码]

std::thread::id的实际实现依赖操作系统API。例如:

  • 在Linux中可能封装pthread_t
  • 在Windows中可能使用DWORD类型的线程ID。

可通过以下方式验证平台差异:

  
#include <iostream>  
#include <thread>  
#include <sstream>  

int main() {  
    std::stringstream ss;  
    ss << std::this_thread::get_id();  
    std::cout << "Thread ID as string: " << ss.str() << '\n';  
}

总结[编辑 | 编辑源代码]

  • std::thread::id是C++标准库中用于标识线程的核心工具。
  • 适用于调试、日志记录、线程特定数据管理等场景。
  • 支持比较、哈希和流输出,兼容STL容器。

模板:Stub