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可以用于将任务分发给不同的线程。例如,一个任务队列可以分发任务给一组线程,并使用线程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.mzph.cn/news/104741.shtml

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

相关文章

Qt 窗口与部署应用程序发布包 day6

Qt 窗口与部署应用程序发布包 day6 QWidget QWidget是所有可视控件的基类&#xff0c;每个控件都是矩形按照Z轴顺序排序如果控件没有父控件&#xff0c;则称为窗口 设置exe窗口图标 在项目文件中新建一个文件夹Resource&#xff0c;来存放图标文件 第一种方法 用绝对路…

UE4和C++ 开发--HUD类

HUD 平视显示器(Head Up Display),简称HUD。在蓝图中是指在屏幕上面绘制的二维物体。 1. 创建HUD 打开蓝图编辑器&#xff0c;创建一个蓝图类&#xff0c;搜索HUD&#xff0c;选择并命名BP_HUD。 2. 开始绘制 打开事件列表&#xff0c;右键搜索 EventReceive Draw HUD。有两…

微信picker弹出之后 , 背景变成灰色是怎么做的

微信小程序在弹出picker组件时&#xff0c;会将页面背景变为半透明的灰色&#xff0c;这是通过设置一个全屏的蒙层来实现的。 具体实现方法如下&#xff1a; 在WXML文件中&#xff0c;添加一个view元素作为蒙层&#xff0c;并设置其样式和属性&#xff1a; <view class&q…

互联网Java工程师面试题·Java 并发编程篇·第三弹

目录 26、什么是线程组&#xff0c;为什么在 Java 中不推荐使用&#xff1f; 27、为什么使用 Executor 框架比使用应用创建和管理线程好&#xff1f; 27.1 为什么要使用 Executor 线程池框架 27.2 使用 Executor 线程池框架的优点 28、java 中有几种方法可以实现一个线程…

【牛客网刷题(数据结构)】:环形链表的约瑟夫问题

描述 编号为 1 到 n 的 n 个人围成一圈。从编号为 1 的人开始报数&#xff0c;报到 m 的人离开。 下一个人继续从 1 开始报数。 n-1 轮结束以后&#xff0c;只剩下一个人&#xff0c;问最后留下的这个人编号是多少&#xff1f; O(n) 示例1 好环形链表的约瑟夫问题是一个经典的问…

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

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

Vue_Bug NPM下载速度过慢

Bug描述&#xff1a; NPM下载速度过慢 解决方法&#xff1a; 将NPM的默认下载源换成国内镜像源 查看当前下载源的命令&#xff1a; npm config get registry换成淘宝镜像源的命令&#xff1a; npm config set registry https://registry.npmmirror.com/

微信小程序(小程序入门)

一&#xff0c;介绍 1、什么是小程序 小程序是一种轻量级的应用程序&#xff0c;可以在移动设备上运行&#xff0c;不需要用户下载和安装。它们通常由企业或开发者开发&#xff0c;用于提供特定功能或服务。 微信小程序&#xff08;wei xin xiao cheng xu&#xff09;&#xf…

O3DE社区发布2310.0版本

O3DE社区在今年10月10日发布了版本2310.0。 2310.0版本对应的代码标签&#xff0c;见链接。 直接下载标签2310.0对应的源码&#xff0c;命令如下&#xff1a; git clone https://github.com/o3de/o3de.git -b 2310.0或者本地已经clone过项目&#xff0c;可以通过切换分支的方…

easyUI重新渲染

问题 使用Easyui 时&#xff0c;动态后添加的元素样式无法生效。 解决颁发 全页面重新渲染 $.parser.parse();单一元素重新渲染 var obj $("#div1").append("<input classeasyui-textbox typetext>"); $.parser.parse(obj);

NPM相关命令

临时使用 npm --registry https://registry.npm.taobao.org install 包名2.永久设置为淘宝镜像 npm config set registry https://registry.npm.taobao.org3.换回国外官方源 npm config set registry https://registry.npmjs.org4.查看使用的源地址 npm config get registr…

内部类概述

一、内部类 1.内部类概述 2.内部类的四种实现形式 1.成员内部类 public class Outer {private int age99;public static String a;//成员内部类public class Inner{private int age88;private String name; // public static String school; //jdk 16开始才支持定义静态…

关于safari浏览器浏览html video标签无法正常播放的问题

问题&#xff1a; 前端demo使用一个video标签包含一个非静态资源的mp4文件。在chrome浏览器下可以正常展示&#xff0c;但是safari却不可以。 原因&#xff1a; 1. mp4文件必须用ffmpeg合成的&#xff0c;其他压缩的mp4文件是不可能展示的。请确定mp4文件并用正常的ffmpeg进…

nvm、node、npm解决问题过程记录

在Windows10如何降级Node.js版本&#xff1a;可以尝试将Node.js版本降级到一个较旧的版本&#xff0c;以查看问题是否得以解决。可以使用Node Version Manager (nvm) 来轻松切换Node.js版本&#xff0c;具体完整步骤&#xff1a; 首先&#xff0c;需要安装Node Version Manager…

C++项目:【负载均衡式在线OJ】

文章目录 一、项目介绍 二、技术栈与开发环境 1.所用技术: 2.开发环境&#xff1a; 三、项目演示 1.运行代码 2.进入项目首页 3.题目列表 4.点击具体一道题 5.编辑代码并提交 四、项目思维导图 五、项目宏观结构 六、Comm公共模块 1.日志工具log.hpp 2.其他工具…

SpringEL:SpEL表达式文本转译

目录 1.效果展示 2.实现方法 在项目开发中&#xff0c;后端研发定义的规则表达式&#xff0c;由于掺杂字段定义、操作符、具体数值等&#xff0c;对业务运营人员比较晦涩难懂&#xff0c;不易理解&#xff0c;解释成本也比较高&#xff0c;为了更好将规则表达式的含义触达业务…

多线程并发篇---第十篇

系列文章目录 文章目录 系列文章目录一、Java线程池中队列常用类型有哪些?二、线程安全需要保证几个基本特征?三、说一下线程之间是如何通信的?一、Java线程池中队列常用类型有哪些? ArrayBlockingQueue 是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则…

如何在 Spring Boot 中进行分布式追踪

在 Spring Boot 中进行分布式追踪 分布式系统中的应用程序由多个微服务组成&#xff0c;它们可以位于不同的服务器、容器或云中。当出现问题时&#xff0c;如性能瓶颈、错误或延迟&#xff0c;了解问题的根本原因变得至关重要。分布式追踪是一种用于跟踪和分析分布式应用程序性…

linux安装filebeat并收集日志到elasticsearch

摘要&#xff1a; 通过filebeat收集服务器上各个应用的日志到elasticsearch&#xff0c;通过tags区分不同的应用创建不同的索引保存日志。 官网地址&#xff1a; https://www.elastic.co/cn/downloads/past-releases#filebeat 安装步骤&#xff1a; 1&#xff1a;下载并解…

linux8使用yum安装reids流程

准备安装环境 yum install -y gcc tcl gcc-c make 使用yum进行处理问题 yum install redis -y 安装完成之后会有/etc/redis.conf&#xff0c;我们需要进行一个备份操作 cp /etc/redis.conf /home/redis/ 启动redis服务测试 能否登录 systemctl start redis systemctl st…