当前位置: 首页 > news >正文

C++高频知识点(三十)

文章目录

  • 146. C++11 中的 std::future 和 std::async 用法?
    • 使用方法
    • std::async 的执行策略
    • 146.3 结合 std::promise与 std::future
    • 注意事项
  • std::unique_lock与std::lock_guard的区别是什么?
    • 功能对比
    • std::lock_guard
    • std::unique_lock
      • (1)延迟锁定
      • (2)尝试锁定
      • (3)显式解锁和重新锁定
  • 148. static_cast和dynamic_cast区别?
    • static_cast 示例
    • dynamic_cast 示例
  • 149. C++中如何实现一个简单的命令模式的示例?
    • 代码示例
  • 150. 对OpenGL 渲染管线了解吗?
    • 渲染管线的主要流程
      • 1. 输入阶段(准备数据)
      • 2. 顶点着色器阶段
      • 3. 图元装配与光栅化
      • 4. 片段着色器阶段
      • 5. 测试与混合
      • 6. 输出图像

同步:完成这一步才能进行下一步。异步:不等待,完成后再回调处理。阻塞:调用者被迫等待,非阻塞:调用者不必等待。

146. C++11 中的 std::future 和 std::async 用法?

std::future 和 std::async 是 C++11 引入的线程支持库的一部分,主要用于 异步操作 和 线程结果的获取,大大简化了多线程编程的复杂性。

在这里插入图片描述

使用方法

#include <iostream>
#include <future>
#include <thread>// 一个耗时计算函数
int slowFunction(int x) {std::this_thread::sleep_for(std::chrono::seconds(3)); // 模拟耗时操作return x * x;
}int main() {// 使用 std::async 启动异步任务/*std::async:是 C++11 中引入的异步任务启动机制,用来启动一个异步任务,返回一个 std::future 对象。这个任务会在后台线程执行。std::launch::async:表示异步启动,即强制在新的线程中执行 slowFunction。这意味着 slowFunction 在主线程外的另一个线程中运行。slowFunction:需要被异步执行的函数。10:是传递给 slowFunction 的参数,slowFunction(10) 会被调用,返回 10 的平方。*/std::future<int> result = std::async(std::launch::async, slowFunction, 10);std::cout << "Doing other work while waiting for the result...\n";// 获取异步任务的结果(阻塞,直到任务完成)// std::future 提供了 get() 方法来获取异步任务的结果。如果任务还没有完成,调用 get() 会阻塞当前线程,直到任务完成并返回结果int value = result.get();std::cout << "Result is: " << value << std::endl;return 0;
}

在这里插入图片描述

std::async 的执行策略

在这里插入图片描述

#include <iostream>
#include <future>int compute(int x) {std::cout << "Computing...\n";return x * 2;
}int main() {// 异步策略std::future<int> asyncResult = std::async(std::launch::async, compute, 10);// 延迟策略/*std::launch::deferred:表示采用延迟执行策略。这个策略意味着 compute(20) 函数不会立即在后台线程执行,而是当调用 deferredResult.get() 时,任务才会在主线程中执行。换句话说,延迟策略不会在异步任务启动时就开始计算,而是等到请求结果时才执行计算。compute:指定要延迟执行的函数。20:传递给 compute 函数的参数,这里是 20*/std::future<int> deferredResult = std::async(std::launch::deferred, compute, 20);std::cout << "Other work is being done...\n";// 获取异步策略结果(任务已在后台运行)std::cout << "Async result: " << asyncResult.get() << std::endl;// 获取延迟策略结果(此时才运行任务)std::cout << "Deferred result: " << deferredResult.get() << std::endl;return 0;
}

在这里插入图片描述

146.3 结合 std::promise与 std::future

  • std::promise 用于设置共享状态的值
  • std::future 用于获取共享状态的值
#include <iostream>
#include <future>
#include <thread>void computeSquare(std::promise<int>&& prom, int x) {std::this_thread::sleep_for(std::chrono::seconds(2));prom.set_value(x * x); // 设置结果
}int main() {std::promise<int> prom;               // 创建 promise (它就像是倒斗中的斗 摸金校尉的工具)std::future<int> fut = prom.get_future(); // 获取 futurestd::thread t(computeSquare, std::move(prom), 10);std::cout << "Waiting for the result...\n";int result = fut.get(); // 获取异步结果(阻塞)std::cout << "Result is: " << result << std::endl;t.join();return 0;
}

在这里插入图片描述

注意事项

在这里插入图片描述

std::unique_lock与std::lock_guard的区别是什么?

在这里插入图片描述

功能对比

在这里插入图片描述

std::lock_guard

在这里插入图片描述

#include <iostream>
#include <mutex>
#include <thread>std::mutex mtx;void safeFunction() {std::lock_guard<std::mutex> guard(mtx); // 自动锁定std::cout << "Thread-safe operation\n";// 离开作用域时自动解锁
}int main() {std::thread t1(safeFunction);std::thread t2(safeFunction);t1.join();t2.join();return 0;
}

std::unique_lock

  • 提供灵活的锁管理功能。
  • 支持延迟锁定、尝试锁定和超时锁定。
  • 可以显式解锁(unlock())或重新锁定(lock())。

(1)延迟锁定

#include <iostream>
#include <mutex>
#include <thread>std::mutex mtx;void safeFunction() {std::unique_lock<std::mutex> lock(mtx, std::defer_lock); // 延迟锁定//// 执行一些操作,不需要锁lock.lock(); // 显式锁定std::cout << "Thread-safe operation\n";// 离开作用域时自动解锁
}int main() {std::thread t1(safeFunction);std::thread t2(safeFunction);t1.join();t2.join();return 0;
}

(2)尝试锁定

#include <iostream>
#include <mutex>
#include <thread>std::mutex mtx;void safeFunction() {/*std::try_to_lock 表示我们不等待锁定,而是尝试锁定,如果当前锁已经被其他线程锁住了,它会立即返回并不会阻塞当前线程。如果锁定成功,lock 会管理对 mtx 的持有。如果锁定失败,lock 将不会持有 mtx,并且会进入 else 分支。if (lock.owns_lock()):检查 lock 是否成功持有锁。*/std::unique_lock<std::mutex> lock(mtx, std::try_to_lock); // 尝试锁定if (lock.owns_lock()) {std::cout << "Acquired the lock\n";} else {std::cout << "Failed to acquire the lock\n";}
}int main() {std::thread t1(safeFunction);std::thread t2(safeFunction);t1.join();t2.join();return 0;
}

在这里插入图片描述

(3)显式解锁和重新锁定

#include <iostream>
#include <mutex>
#include <thread>std::mutex mtx;void safeFunction() {std::unique_lock<std::mutex> lock(mtx); // 自动锁定std::cout << "Critical section\n";lock.unlock(); // 手动解锁// 非临界区操作lock.lock();   // 手动重新锁定std::cout << "Critical section again\n";
}int main() {std::thread t1(safeFunction);std::thread t2(safeFunction);t1.join();t2.join();return 0;
}

148. static_cast和dynamic_cast区别?

在这里插入图片描述
在这里插入图片描述

static_cast 示例

#include <iostream>
class Base {};
class Derived : public Base {};int main() {Base* base = new Derived();// 不安全的类型转换:无运行时检查Derived* derived = static_cast<Derived*>(base); if (derived) {std::cout << "static_cast 成功\n";}delete base;return 0;
}

dynamic_cast 示例

#include <iostream>
class Base {
public:virtual ~Base() {} // 必须是多态类
};
class Derived : public Base {};
class AnotherDerived : public Base {};int main() {Base* base = new AnotherDerived();// 安全的类型转换:有运行时检查Derived* derived = dynamic_cast<Derived*>(base); if (derived) {std::cout << "dynamic_cast 成功\n";} else {std::cout << "dynamic_cast 失败\n";}delete base;return 0;
}

149. C++中如何实现一个简单的命令模式的示例?

在这里插入图片描述
假设你有一个远程控制器,它不直接控制具体的设备(比如电灯),而是触发一个命令。不同的遥控器可能控制不同的设备,比如电视、空调或电灯。如果我们使用命令模式,那么每个设备的开关操作都会封装为一个命令对象,遥控器只需要知道如何“执行命令(只管发命令,你使劲儿按遥控器,具体能不能打开电视,那是电视的事儿)”,而不关心具体设备的实现。这就是命令模式的精髓所在。

代码示例

可以看我的文章,里面的代码结构更好深入浅出设计模式——行为型模式之命令模式 Command

#include <iostream>
using namespace std;// Command接口
class Command {
public:virtual ~Command() {}virtual void execute() = 0;  // 执行命令
};// 电灯类(接收者  这货才真正负责执行)
class Light {
public:void turnOn() {cout << "The light is on." << endl;}void turnOff() {cout << "The light is off." << endl;}
};// 开灯命令(对命令进行定义,命令定义中唤醒执行者)
class LightOnCommand : public Command {
private:Light* light;  // 这里持有一个Light对象的指针public:LightOnCommand(Light* l) : light(l) {}void execute() override {light->turnOn();  // 调用Light类的turnOn方法}
};// 关灯命令
class LightOffCommand : public Command {
private:Light* light;  // 这里持有一个Light对象的指针public:LightOffCommand(Light* l) : light(l) {}void execute() override {light->turnOff();  // 调用Light类的turnOff方法}
};// 遥控器(Invoker)对命令进行集成,遥控器上可以弄过个命令
class RemoteControl {
private:Command* command;public:RemoteControl() : command(nullptr) {}void setCommand(Command* cmd) {command = cmd;}void pressButton() {if (command) {command->execute();  // 执行当前命令}}
};int main() {// 创建接收者(电灯)Light* light = new Light();// 创建命令对象,并传入Light对象Command* lightOn = new LightOnCommand(light);Command* lightOff = new LightOffCommand(light);// 创建遥控器RemoteControl* remote = new RemoteControl();// 按下遥控器按钮,开灯remote->setCommand(lightOn);remote->pressButton();// 按下遥控器按钮,关灯remote->setCommand(lightOff);remote->pressButton();// 清理内存delete lightOn;delete lightOff;delete light;delete remote;return 0;
}

在这里插入图片描述

150. 对OpenGL 渲染管线了解吗?

渲染管线是指将一个三维场景转换成二维图像的完整流程,它是一条流水线式的处理过程,每个阶段都负责完成特定的任务。通过渲染管线,我们把计算机里的模型、纹理和光照,变成最终显示在屏幕上的图像。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

渲染管线的主要流程

以 OpenGL 为例,现代的渲染管线分为几个主要阶段:

1. 输入阶段(准备数据)

  • 输入顶点数据:提供物体的基本信息,包括点的坐标、颜色、纹理等。
  • 例子:> “我要画一个三角形,它有三个顶点,每个顶点的位置和颜色是这样的。”

2. 顶点着色器阶段

在这里插入图片描述

3. 图元装配与光栅化

在这里插入图片描述

4. 片段着色器阶段

在这里插入图片描述

5. 测试与混合

在这里插入图片描述

6. 输出图像

  • 最终把处理好的像素数据显示在屏幕上。

之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!

http://www.dtcms.com/a/340508.html

相关文章:

  • 嵌入式音频开发(3)- AudioService核心功能
  • 机器学习数学基础与商业实践指南:从统计显著性到预测能力的认知升级
  • Node.js中的Prisma应用:现代数据库开发的最佳实践
  • 河南萌新联赛2025第六场 - 郑州大学
  • Java:将视频上传到腾讯云并通过腾讯云点播播放
  • 【Task02】:四步构建简单rag(第一章3节)
  • 第三阶段数据-4:SqlHelper类,数据库删除,DataTable创建
  • 【考研408数据结构-08】 图论基础:存储结构与遍历算法
  • Opencv模板匹配
  • 27.语言模型
  • Java + 工业物联网 / 智慧楼宇 面试问答模板
  • C#APP.Config配置文件解析
  • 案例分享:BRAV-7123助力家用型人形机器人,智能生活未来已来
  • 项目各功能介绍
  • 今天我们学习计算机网络技术的虚拟局域网VLAN以及了解三层交换机的概念
  • 应用在运行时,向用户索取(相机、存储)等权限,未同步告知权限申请的使用目的,不符合相关法律法规要求--教你如何解决华为市场上架难题
  • leetcode 1277. 统计全为 1 的正方形子矩阵 中等
  • (nice!!!)(LeetCode 每日一题) 1277. 统计全为 1 的正方形子矩阵 (动态规划)
  • Tumblr长文运营:亚矩阵云手机助力多账号轮询与关键词布局系统
  • 亚矩阵:跨境卖家 YouTube 私域矩阵搭建的高效解决方案
  • JavaScript 性能优化实战:从原理到落地的完整指南
  • AI硬件 - 华为显卡的演进
  • 深入理解MySQL Ⅳ -- SQL性能分析工具
  • 力扣48:旋转矩阵
  • [TryHackMe]Mr Robot CTF(hydra爆破+Wordpress更改主题)
  • IPSec安全概述
  • 医疗AI与医院数据仓库的智能化升级:异构采集、精准评估与高效交互的融合方向(上)
  • 信创产品TongLinkQ安装及springboot2整合使用
  • AI 视频翻译工具的调研笔记
  • Spring Boot 实战:从项目搭建到部署优化