网站建设推荐华网天下/自助网站建设
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分配和使用方式可能因编程语言和操作系统而异。
相关文章:

C++笔记之获取线程ID以及线程ID的用处
C笔记之获取线程ID以及线程ID的用处 code review! 文章目录 C笔记之获取线程ID以及线程ID的用处一.获取ID二.线程ID的用处2.1.线程池管理2.2.动态资源分配2.3.使用线程同步机制实现互斥访问共享资源2.4.使用线程 ID 辅助线程同步2.5.任务分发:线程ID可以用于将任务…...

机器人硬件在环仿真:解决实体开发与测试挑战,提升效率与安全性
工业机器人具备出色的灵活性和运动能力,广泛应用于工业制造领域。它们可以完成装配、焊接、喷涂、搬运、加工、品质检测等任务,提高了生产效率,保证了产品质量。此外,在医疗领域也有辅助手术等特殊应用,展现了其在多个…...

stream()
stream().map,stream().filter,stream().peek 1、stream().map:该方法用于将一个流中的元素通过指定的函数进行映射,最终生成一个新的流。例如,如果我们有一个存储了字符串的列表,可以使用 map 方法将列表…...

VBA之正则表达式(43)-- 从网页中提取指定数据
实例需求:由网页中提取下图中颜色标记部分内容,网页中其他部分与此三行格式相同。 方法1 Sub Demo()Dim objRegex As ObjectDim inputString As StringDim objMatches As ObjectDim objMatch As ObjectSet objRegex CreateObject("VBScript.RegEx…...

Elucidating the Design Space of Diffusion-Based Generative Models 阅读笔记
文章使用模块化(modular)的思想,分别从采样、训练、score network设计三个方面分析和改进diffusion-based models。 之前的工作1已经把diffusion-based models统一到SDE或者ODE框架下了,这篇文章的作者同样也从SDE和ODE的角度出发…...

计算机网络 | 传输层
计算机网络 | 传输层 计算机网络 | 传输层功能概述 参考视频:王道计算机考研 计算机网络 参考书:《2022年计算机网络考研复习指导》 计算机网络 | 传输层 功能概述 传输层是主机才有的层次。 复用:发送方的不同应用进程都可以使用同一个传…...

Android 13 隐私权限和安全变更之通知
介绍 根据官网https://developer.android.com/about/versions/13/summary?hlzh-cn展示的Android 13 功能和变更列表中提及的,Android 13(API 级别 33)引入了新的权限POST_NOTIFICATIONS。 使用 在Android 13及以上版本,如需向…...

docker-compose安装和使用(自启、redis、mysql、rabbitmq、activemq、es、nginx、java应用)
1.在线安装docker-compose: 参考官网:https://docs.docker.com/compose/install/other/ docker-compose安装及简单入门 [Docker] docker-compose使用教程 Docker系列教程22-docker-compose.yml常用命令 # 安装(加速下载https://ghproxy.…...

dll文件缺失,ps,pr无法打开,游戏运行不了如何解决
最近重装了系统,然后打开原来的软件发现都会报错,说***.dll文件缺失 于是找了很多解决办法 方案一 说是下载一个dll文件恢复助手,一键恢复 不要信 统统不管用,不是收费高就是没作用 方案二 下载对应dll文件去c盘对应软件位置…...

前后端数据导入导出Excel
一:导入 Excel有读取也便有写出,Hutool针对将数据写出到Excel做了封装。 原理 Hutool将Excel写出封装为ExcelWriter,原理为包装了Workbook对象,每次调用merge(合并单元格)或者write(写出数据&…...

RackNerd 圣何塞 VPS 测评
发布于 2023-07-06 on https://chenhaotian.top/vps/racknerd-ca/ RackNerd 圣何塞 VPS 测评 官网链接:https://my.racknerd.com/index.php?rp/store/kvm-vps 这款是2022年双十一特别款,现在已经买不到了 网络是G口,4T流量 稳定性不错&…...

php74 安装sodium
下载编译安装libsodium wget https://download.libsodium.org/libsodium/releases/libsodium-1.0.18-stable.tar.gz tar -zxf libsodium-1.0.18-stable.tar.gz cd libsodium-stable ./configure --without-libsodium make && make check sudo make install下载编译安装…...

优思学院:想成为质量工程师?了解质量工程师职责和能力是关键!
在职场中,质量工程师的角色显得至关重要。但如果你不清楚质量工程师的工作职责以及所需具备的能力,那么这个岗位可能会显得遥不可及。本文将为你详细介绍质量工程师的工作内容以及如何选择适合自己的质量工程师岗位。 一、质量工程师的工作职责 1. 质量…...

Rollup failed to resolve import
问题描述 我在打包vue3的项目的时候报了以下错误 问题原因 打包时,静态资源目录没有识别出来,导致打包终止并报错 问题解决 需要把路径改为跟路径,就可以打包啦 错误资源路径写法 <img src"src/assets/image/底部导航背景/book2…...

基于VScode 使用plantUML 插件设计状态机
本文主要记录本人初次在VScode上使用PlantUML设计 本文只讲述操作的实际方法,假设java已安装成功 。 1. 在VScode下安装如下插件 2. 验证环境是否正常 新建一个文件夹并在目录下面新建文件test.plantuml 其内容如下所示: startuml hello world skinparam Style …...

2023年中国汽车智能工厂市场规模不断增大,智能化已成趋势[图]
汽车智能工厂是在数字化工厂的基础上,通过互联网技术与工业技术结合,数据监管设备以及AI等技术的结合,实现汽车整车从原材料及零部件的生产到运输、组装一系列的自动化生产。汽车智能工厂很大程度上降低成本和人为干扰,实现自动化…...

cola架构:一种扩展点的实现思路浅析
目录 1.扩展点使用实例 2.主要技术点 2.1 注解加持 2.2 注解解析 2.3 扩展点路由 在实际项目中,我们经常使用策略模式、或者状态模式来隔离同一接口下不同的实现逻辑,进而消除代码中ifelse硬编码分支,使代码结构更清晰,也大大…...

Thread常用API
setname方法每个线程取名 需要创建构造器 线程设置名字 package Thread_api_test;// 继承Thread类 public class MyThread extends Thread {//创建构造器 线程设置名字public MyThread(String name){super(name);}Overridepublic void run() {super.run();Thread mThread.cur…...

系列九、Redis的发布订阅
一、概述 Redis的发布订阅是进程间的一种消息通信模式,发送者(Publisher)发送消息,订阅者(Subscriber)接收消息。 二、命令 三、案例演示 3.1、订阅单个 客户端订阅 cctv-1、cctv-2、 cctv-3三个频道 SUB…...

《TypeScript》系列之对比JavaScript,TypeScript的优势
概述 TypeScript是微软公司开发的一种基于JavaScript语言的编程语言,它的目的并不是创造一种全新的语言,而是增强JavaScript的功能,使其更适合多人合作的企业级项目。TypeScript可以看做是JavaScript的超集,即它继承了后者的全部…...

Notepad++使用技巧
显示远程连接的文件目录 自动完成:函数自动提示 自动输入:输入一半括号自动补全另一半 自动关联 .pc文件识别为C 列模式 按住Alt不松手,可以直接范围选择,便于编辑选择的区域 关键行筛选 1.进入搜索页面的标记 2.选中标…...

React 中报Type error: Could not find a declaration file for module ‘qs‘.(已解决)
ts项目引入qs 比如 nextjs 或者reactjs npm install --save-dev types/qs 确保你的tsconfig.json文件中有以下设置 {"compilerOptions": {"types": ["qs"]}} 如果你的项目中没有tsconfig.json文件,你可以创建一个。在项目根目录下创…...

【Linux】:Linux环境与版本
以下哪个命令输出Linux内核的版本信息 A.uname -r B.vmstat C.sar D.stat uname -r 查看linux内核版本信息 vmstat 报告关于内核线程、虚拟内存、磁盘、陷阱和 CPU 活动的统计信息 sar 主要帮助我们掌握系统资源的使用情况,特别是内存和CPU的使用情况 stat 用于显示…...

PNG转EPS,包括Latex导入
在电脑TEXLIVE文件夹里中找到bmeps.exe TEXLIVE\2022\bin\win32 可以新建一个文件夹picture(图片和exe文件必须在一个文件夹里),将bmeps.exe复制出来,方便后续大量图片操作 导入png图片 新建一个txt文件,命名为Fig1.…...

Visual Studio 2022 cmake编译 PP-OCRv4
1 环境准备 下载PaddleOCR PaddleOCR C 部署代码位于 PaddleOCR\deploy\cpp_infer目录下 paddle_inference paddle_inference opencv 这里使用已经安装好的opencv4.5.5下载dirent-master.zip 下载dirent-master.zip, 解压并复制dirent.h文件到PaddleOCR\deploy\cpp_infer目录下…...

学习笔记|串口与PC通信的接线|移植驱动程序|串口通信实战|STC32G单片机视频开发教程(冲哥)|第二十一集(上):串口与PC通信
目录 1.串口与PC通信的接线芯片与芯片之间的通讯:芯片与电脑之间的通讯: 2.利用实验箱示例代码移植驱动程序3.串口通信实战最小工程代码移植编译提示错误:undefined identifier 1.串口与PC通信的接线 上节试验是串口和电脑进行一个通信&…...

关于Mybaits缓存....
记Mybaits缓存踩的坑 1.问题提出 最近开发一个记录操作前后修改内容的功能,获取修改前数据比较简单,直接从数据库获取,记录修改后的功能也比较简单,直接将用户修改的内容封装成po对象,然后两个比对就可以了ÿ…...

Vue axios调用springboot接口获取数据库数据并显示到网页
axios调用接口获取数据 可以查看简述化的此文 点击 此文简述化文章 PS**由于我自己的本次springboot项目内容很多,所以只是截取了其中关于axios调用接口获取数据的内容,还请大家了解工作原理即可** 前端 添加axios和vue2链接 <script src"htt…...

12-bean创建流程3
文章目录 1 bean实例化前 2. bean实例化doCreateBean() 1 bean实例化前 createBean方法里面的resolveBeforeInstantiation方法,InstantiationAwareBeanPostProcessor接口创建一个代理对象返回 try {// Give BeanPostProcessors a chance to return a p…...

volatile关键字 和 i = i + 1过程
本文是复制粘贴,请直接看原文 原文链接:Java并发编程:volatile关键字解析 - Matrix海子 - 博客园 (cnblogs.com) ------------------------------------------------------------------------------------------------------------------- Java并发编程࿱…...