C++笔记之获取线程ID以及线程ID的用处

news/2024/5/9 15:34:42/文章来源:https://blog.csdn.net/weixin_43297891/article/details/133828556

C++笔记之获取线程ID以及线程ID的用处

code review!
在这里插入图片描述

文章目录

  • C++笔记之获取线程ID以及线程ID的用处
    • 一.获取ID
    • 二.线程ID的用处
      • 2.1.线程池管理
      • 2.2.动态资源分配
      • 2.3.使用线程同步机制实现互斥访问共享资源
      • 2.4.使用线程 ID 辅助线程同步
      • 2.5.任务分发:线程ID可以用于将任务分发给不同的线程。例如,一个任务队列可以分发任务给一组线程,并使用线程ID来跟踪任务的状态和进度。
      • 2.6.线程间通信:线程可以使用线程ID来识别接收消息的线程。这可用于实现多线程间的消息传递或共享数据。

一.获取ID

std::this_thread::get_id() 是 C++ 标准库中的一个函数,用于获取当前线程的唯一标识符。这个标识符通常是一个对象,它可以与其他线程的标识符进行比较,以确定它们是否代表同一线程。

以下是 std::this_thread::get_id() 的基本用法:

#include <iostream>
#include <thread>int main() {// 获取当前线程的标识符std::thread::id threadId = std::this_thread::get_id();// 将标识符打印到标准输出std::cout << "Thread ID: " << threadId << std::endl;return 0;
}

在上面的示例中,std::this_thread::get_id() 被用来获取当前线程的标识符,并将其打印到标准输出。这个标识符通常是一个唯一的值,可以用来区分不同的线程。

请注意,std::this_thread::get_id() 返回的是一个 std::thread::id 类型的对象,可以使用 ==!= 运算符来比较两个线程的标识符,以确定它们是否相同。这对于多线程编程中的线程管理和同步非常有用。

上面的例子获取的是主线程的 ID。在 main 函数中调用 std::this_thread::get_id() 会返回主线程的唯一标识符。在多线程应用程序中,每个线程都有自己的唯一标识符,包括主线程。你可以在任何线程中使用 std::this_thread::get_id() 来获取该线程的标识符,不仅仅是主线程。

如果你在多线程程序中创建了其他线程,你可以在这些线程中使用 std::this_thread::get_id() 来获取它们各自的标识符,以便在需要时进行线程识别和管理。每个线程都有自己的标识符,这有助于区分和跟踪线程的行为。

二.线程ID的用处

2.1.线程池管理

在线程池中,线程 ID 可以帮助你识别特定工作者线程。例如,你可以将任务分配给特定的线程,以便更精确地控制资源分配和任务调度。

#include <iostream>
#include <thread>
#include <vector>
#include <functional>
#include <future>void worker(int id) {std::cout << "Worker " << id << " is executing." << std::endl;// 执行任务
}int main() {int numThreads = 4;std::vector<std::thread> threads;for (int i = 0; i < numThreads; ++i) {threads.push_back(std::thread(worker, i));}// 等待所有工作者线程完成for (auto& thread : threads) {thread.join();}std::cout << "All workers finished." << std::endl;return 0;
}

在这个示例中,线程 ID 有助于标识线程池中的不同工作者线程。

2.2.动态资源分配

线程 ID 可以用于动态分配资源给不同的线程。例如,你可以为特定线程分配不同的计算资源或内存区域,以提高性能或实现隔离。

#include <iostream>
#include <thread>void worker(int id) {// 执行需要大量内存的计算任务// 分配特定的内存区域std::cout << "Worker " << id << " is executing." << std::endl;// 释放内存区域
}int main() {int numThreads = 4;std::vector<std::thread> threads;for (int i = 0; i < numThreads; ++i) {threads.push_back(std::thread(worker, i));}for (auto& thread : threads) {thread.join();}std::cout << "All workers finished." << std::endl;return 0;
}

对于线程 ID 用于动态分配资源的示例,考虑以下情况:你希望为不同的线程分配不同的计算资源以优化性能。在这种情况下,你可以使用线程 ID 来识别和区分不同的线程,并为它们分配不同的资源。以下是一个示例:

#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
#include <chrono>// 模拟不同线程需要不同计算资源的任务
void performTask(int id) {std::cout << "Thread " << id << " is performing a task." << std::endl;std::this_thread::sleep_for(std::chrono::seconds(2));std::cout << "Thread " << id << " completed the task." << std::endl;
}int main() {int numThreads = 4;std::vector<std::thread> threads;for (int i = 0; i < numThreads; ++i) {// 根据线程 ID 分配不同的计算资源if (i % 2 == 0) {threads.push_back(std::thread(performTask, i));} else {// 为奇数线程分配更多的计算资源threads.push_back(std::thread([i] {// 分配更多的计算资源performTask(i);}));}}for (auto& thread : threads) {thread.join();}std::cout << "All threads finished." << std::endl;return 0;
}

在这个示例中,有四个线程执行任务,但奇数线程(线程1和线程3)被分配更多的计算资源。通过线程 ID(i)的奇偶性来确定分配不同计算资源的策略。

请注意,这个示例是一个简化的演示,真实的资源分配通常更复杂。线程 ID 可以用于更复杂的分配策略,例如在多核处理器上优化计算资源分配,或在不同的线程之间实现资源隔离。

2.3.使用线程同步机制实现互斥访问共享资源

线程同步是多线程编程中的一个关键概念,它用于确保多个线程能够安全地协同工作,避免数据竞争和并发问题。线程 ID 可以在线程同步中发挥重要作用,以下是一个示例说明线程同步的用途:

示例:使用线程同步机制实现互斥访问共享资源

在多线程环境中,多个线程可能会同时访问共享资源,如果不进行同步,会导致数据竞争和不确定的行为。为了解决这个问题,我们可以使用互斥锁(std::mutex)来保护共享资源,同时使用线程 ID 来标识哪个线程拥有锁。

#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;  // 用于保护共享资源的互斥锁void worker(int id) {// 一些工作// 使用互斥锁来保护共享资源mtx.lock();std::cout << "Worker " << id << " is accessing the shared resource." << std::endl;// 模拟工作std::this_thread::sleep_for(std::chrono::seconds(1));std::cout << "Worker " << id << " finished accessing the shared resource." << std::endl;mtx.unlock();
}int main() {int numThreads = 4;std::vector<std::thread> threads;for (int i = 0; i < numThreads; ++i) {threads.push_back(std::thread(worker, i));}for (auto& thread : threads) {thread.join();}std::cout << "All workers finished." << std::endl;return 0;
}

在上面的示例中,多个工作者线程(Worker 0、Worker 1、Worker 2、Worker 3)同时访问一个共享资源。互斥锁 mtx 用于保护共享资源,确保一次只有一个线程可以访问。线程 ID 用于标识哪个线程当前拥有锁并在访问共享资源时进行输出。

线程同步是确保多线程程序安全运行的关键部分,使用线程 ID 和互斥锁可以帮助你实现正确的线程同步。这有助于防止并发问题,如竞态条件和数据竞争,从而确保多线程程序的可靠性。

2.4.使用线程 ID 辅助线程同步

线程 ID 并不是直接用于线程同步的工具,而是用于标识不同的线程。然而,线程同步机制(如互斥锁、条件变量等)通常需要用到线程 ID 来实现更复杂的同步逻辑。下面是一个示例,演示如何使用线程 ID 来辅助线程同步。

示例:使用线程 ID 辅助线程同步

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>std::mutex mtx; // 互斥锁
std::condition_variable cv; // 条件变量
int sharedData = 0;void worker(int id) {std::unique_lock<std::mutex> lock(mtx);// 等待主线程发送信号cv.wait(lock, [id] { return id == 1; });// 执行工作std::cout << "Worker " << id << " is accessing shared data: " << sharedData << std::endl;sharedData += id;std::this_thread::sleep_for(std::chrono::seconds(1));// 释放锁lock.unlock();
}int main() {std::thread t1(worker, 1);std::thread t2(worker, 2);// 等待一段时间std::this_thread::sleep_for(std::chrono::seconds(2));// 向线程1发送信号{std::unique_lock<std::mutex> lock(mtx);std::cout << "Main thread is sending a signal to Worker 1." << std::endl;cv.notify_all();}t1.join();t2.join();std::cout << "All workers finished." << std::endl;return 0;
}

在这个示例中,有两个工作者线程(Worker 1 和 Worker 2)。线程 1首先被阻塞在条件变量上等待一个特定信号,然后主线程向线程 1 发送信号,线程 1被唤醒后可以开始执行工作。线程 2只是简单地等待。

线程同步机制包括互斥锁 mtx 和条件变量 cv。线程 ID(id)用于确定哪个线程应该在条件变量上等待信号。线程同步的核心思想是确保线程在正确的时间点执行,并且不会出现竞争条件。

这个示例使用线程 ID 辅助线程同步,但实际上线程同步可能涉及更复杂的逻辑和多个线程之间的交互,线程 ID 通常是用于确定特定线程的条件是否满足,从而执行或等待。

2.5.任务分发:线程ID可以用于将任务分发给不同的线程。例如,一个任务队列可以分发任务给一组线程,并使用线程ID来跟踪任务的状态和进度。

线程ID可以用于将任务分发给不同的线程。例如,一个任务队列可以分发任务给一组线程,并使用线程ID来跟踪任务的状态和进度。

# Python 示例
from threading import Threaddef worker(task_id):# 执行任务print(f"线程 {task_id} 正在执行任务")# 创建多个线程并分发任务
threads = []
for i in range(5):thread = Thread(target=worker, args=(i,))threads.append(thread)thread.start()# 等待所有线程完成
for thread in threads:thread.join()

2.6.线程间通信:线程可以使用线程ID来识别接收消息的线程。这可用于实现多线程间的消息传递或共享数据。

// C++ 示例
#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;
void sendMessage(int senderID, int receiverID, const std::string& message) {std::lock_guard<std::mutex> lock(mtx);std::cout << "线程 " << senderID << " 向线程 " << receiverID << " 发送消息: " << message << std::endl;
}int main() {std::thread thread1(sendMessage, 1, 2, "Hello from Thread 1!");std::thread thread2(sendMessage, 2, 1, "Hi from Thread 2!");thread1.join();thread2.join();return 0;
}

这些示例演示了如何使用线程ID来实现线程同步、任务分发和线程间通信。线程ID用于唯一标识线程,并允许线程之间进行通信和协作。请注意,具体的线程ID分配和使用方式可能因编程语言和操作系统而异。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_560563.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里云服务器不能访问网络之安装mysql 提示连接超时

wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm 过了一段时间后提示 fail .......time out 链接超时 有可能你的服务器不能访问网络 因为宽带套餐 我购买的时候没有购 重新购买就行了

分布式链路追踪如何跨线程

背景 我们希望实现全链路信息&#xff0c;但是代码中一般都会异步的线程处理。 解决思路 我们可以对以前的 Runable 和 Callable 进行增强。 可以使用 ali 已经存在的实现方式。 TransmittableThreadLocal (TTL) 解决异步执行时上下文传递的问题 核心的实现思路如下&#…

一文2000字从0到1手把手教你jmeter分布式压测

一、jmeter为什么要做分布式压测 jmeter本身的局限性 一台压力机的 Jmeter 支持的线程数受限于 Jmeter 其本身的机制和硬件配置&#xff08;内存、CPU等&#xff09;是有限的由于 Jmeter 是 Java 应用&#xff0c;对 CPU 和内存的消耗较大&#xff0c;在需要模拟大量并发用户…

如何恢复红米手机删除的照片/文件?(亲测有效的6 种方式)

如何恢复红米手机删除的照片/文件&#xff1f;&#xff08;亲测有效的6 种方式&#xff09; 凭借出色的相机和实惠的价格&#xff0c;小米红米系列已成为全球知名品牌。但是&#xff0c;最近有人抱怨说他们的红米手机丢失了很多珍贵的照片或视频&#xff0c;希望知道如何从小米…

虚幻阴影整理

虚拟阴影贴图&#xff08;VSM&#xff09;是一种全新的阴影贴图方法&#xff0c;可以提供稳定的高分辨率阴影。通过与虚幻引擎5的Nanite虚拟几何体、Lumen全局光照和反射以及世界分区功能结合使用&#xff0c;它能够实现电影级的品质效果&#xff0c;为大型开放场景提供光照。 …

【漏洞复现】安全云平台存在任意文件下载getshell

漏洞描述 深圳市强鸿电子有限公司鸿运主动安全云平台存在任意文件下载漏洞,攻击者可通过此漏洞下载敏感文件信息。 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律,遵守公共秩序,尊重社会公德,不得利用网络从事危害国家安全、荣誉和利益,未经授权…

深度学习基础知识 BatchNorm、LayerNorm、GroupNorm的用法解析

深度学习基础知识 BatchNorm、LayerNorm、GroupNorm的用法解析 1、BatchNorm2、LayerNorm3、GroupNorm用法&#xff1a; BatchNorm、LayerNorm 和 GroupNorm 都是深度学习中常用的归一化方式。 它们通过将输入归一化到均值为 0 和方差为 1 的分布中&#xff0c;来防止梯度消失和…

想要精通算法和SQL的成长之路 - 连续的子数组和

想要精通算法和SQL的成长之路 - 连续的子数组和 前言一. 连续的子数组和1.1 最原始的前缀和1.2 前缀和 哈希表 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 连续的子数组和 原题链接 1.1 最原始的前缀和 如果这道题目&#xff0c;用前缀和来算&#xff0c;我们的思路…

一篇文章带你用动态规划解决股票购买时机问题

动态规划的解题步骤可以分为以下五步&#xff0c;大家先好好记住 1.创建dp数组以及明确dp数组下标的含义 2.制定递推公式 3.初始化 4.遍历顺序 5.验证结果 股票购买时机问题的解题核心思路 当天的收益是根据前一天持有股票还是不持有股票的状态决定的 那么很自然的我们就想…

【肌电信号】OpenSignals使用方法 --- 肌电信号采集及导入matlab

一、 多通道采集教学 1. 数据线连接 将PLUX设备通过USB或蓝牙与电脑连接&#xff0c;注意确认在几号通道接线。 2.实时数据采集可视化 进行设置。需要在软件中选择你的PLUX设备&#xff0c;并配置相关的参数&#xff0c;如采样率、分辨率、信号类型等 3 支持数据回放和…

DL Homework 4

目录 1 整理一下理论收获 1.1 基础理论 1.2 应用到机器学习 1.3 参数学习 1.4 反向传播算法 2.激活函数 3.神经网络流程推导(包含正向传播和反向传播) 4.数值计算 - 手动计算 5.代码实现 - numpy手推 6.代码实现 - pytorch自动 7.激活函数Sigmoid用PyTorch自带函数torc…

树莓派玩转openwrt软路由:11.OpenWrt安装NodeRed

1、更新软件源 opkg update2、安装nodered docker run -it -p 1880:1880 --name mynodered nodered/node-red3、安装完整性测试 实现一个打印hello world的demo&#xff0c;每隔1秒打印一次

WebAPI+EF连接SQL Server数据库

右击解决方案-添加-新建项目-选择“类库&#xff08;.NET Framework&#xff09;”,新建的项目取名叫WebApi1.EF 添加EF&#xff1a; 新建一个ADO实体数据模型 选择DBFirst 数据源选择MySql 填写数据库地址及账号密码 选择实体框架版本 选择在数据库中的表User 到此配置完成&am…

基于松鼠优化的BP神经网络(分类应用) - 附代码

基于松鼠优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于松鼠优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.松鼠优化BP神经网络3.1 BP神经网络参数设置3.2 松鼠算法应用 4.测试结果&#xff1a;5.M…

对称加密和非对称加密以及CA证书

对称加密 对称加密只用到了公匙,这个公匙是消息的发送方和消息的接收方共享的,也就是消息发送方使用这个公匙对消息加密,然后接收方使用公匙对消息解密,最典型的例子比如像 encrypt 加密,比如我们有个 springboot 应用,需要对 application.yml 文件里的密码做加密,我们…

DAE转换GLB格式

1、DAE模型介绍 DAEA&#xff08;Deep Attentive and Ensemble Autoencoder&#xff09;模型是一种用于无监督学习的深度学习模型&#xff0c;由华为公司提出。DAEA模型结合了自编码器和深度注意力机制&#xff0c;能够对高维数据进行降维和特征提取&#xff0c;并且在处理大规…

探索UI设计|栅格系统的深入分析和应用

界面排版太乱了。你知道网格系统的用途吗&#xff1f;网格系统困扰着许多初级网页设计师&#xff0c;就像一个谜。如果您对网格在设计中的应用有任何疑问&#xff0c;本文是为您量身定制的&#xff0c;并深入分析UI设计中网格系统的基本要素和优点。 什么是网格系统 网格系统…

[计算机进阶] 用户和用户组

1.1 用户和用户组 1.1.1 用户 用户账户是计算机操作系统中用于标识和管理用户身份的概念。 每个用户都拥有一个唯一的用户账户&#xff0c;该账户包含用户的登录名、密码和其他与用户身份相关的信息。 用户账户通常用于验证用户身份&#xff0c;并授权对系统资源的访问权限。…

【Kotlin精简】第3章 类与接口

1 简介 Kotlin类的声明和Java没有什么区别&#xff0c;Kotlin中&#xff0c;类的声明也使用class关键字&#xff0c;如果只是声明一个空类&#xff0c;Kotlin和Java没有任何区别&#xff0c;不过定义类的其他成员会有一些区别。实例化类不用写new&#xff0c;类被继承或者重写…

零基础Linux_17(进程间通信)VSCode环境安装+进程间通信介绍+pipe管道mkfifo

目录 1. VSCode环境安装 1.1 使用VSCode 1.2 远程链接到Linux机器 1.3 VSCode调试 2. 进程间通讯介绍 2.1 进程间通讯的概念和意义 2.2 进程间通讯的策略和本质 3. 管道 3.1 管道介绍 3.2 匿名管道介绍 3.3 匿名管道示例代码 3.3.1 建立管道的pipe 3.3.2 匿名管道…