windows C++-移除界面工作线程(一)
本文档演示了如何使用并发运行时将 Microsoft 基础类 (MFC) 应用程序中由用户界面 (UI) 线程执行的工作移动到工作线程。 本文档还演示了如何提高冗长绘制操作的性能。
通过将阻塞性操作(例如,绘制)卸载到工作线程来从 UI 线程中移除工作,可以提高应用程序的响应能力。本文使用可生成 Mandelbrot 分形的绘制例程来演示一个冗长的阻塞性操作。 Mandelbrot 分形的生成也非常适合并行化,因为每个像素的计算都是独立于所有其他计算的。
创建 Visual C++ MFC 应用程序
使用“MFC 应用程序向导”创建具有所有默认设置的 MFC 应用程序。 有关如何为 Visual Studio 版本打开向导的说明,请参阅演练:使用新的 MFC Shell 控件。
为项目键入一个名称,例如 Mandelbrot,然后单击“确定”以显示“MFC 应用程序向导”。
在“应用程序类型”窗格中,选择“单个文档”。 确保清除“文档/视图体系结构支持”复选框。
单击“完成”以创建项目并关闭“MFC 应用程序向导”。
通过生成并运行应用程序来验证其是否已成功创建。 若要生成应用程序,请在“生成”菜单上单击“生成解决方案”。 如果应用程序已成功生成,请单击“调试”菜单上的“开始调试”来运行应用程序。
实现 Mandelbrot 应用程序的串行版本
本部分介绍了如何绘制 Mandelbrot 分形。 此版本将 Mandelbrot 分形绘制到 GDI+ 位图对象,然后将该位图的内容复制到客户端窗口。下面的代码实现 Mandelbrot 应用程序的串行版本:
// 1.在 pch.h(在 Visual Studio 2017 及更早版本中为 stdafx.h)中,添加以下 #include 指令:#include <memory>// 2. 在 ChildView.h 中,在 pragma 指令后面定义 BitmapPtr 类型。
// BitmapPtr 类型允许使用一个指向要由多个组件共享的 Bitmap 对象的指针。
// 当任何组件都不再引用 Bitmap 对象时,该对象将被删除。typedef std::shared_ptr<Gdiplus::Bitmap> BitmapPtr;// 3. 在 ChildView.h 中,将以下代码添加到 CChildView 类的 protected 部分:protected:// Draws the Mandelbrot fractal to the specified Bitmap object.void DrawMandelbrot(BitmapPtr);protected:ULONG_PTR m_gdiplusToken;// 4. 在 ChildView.cpp 中,注释掉或移除以下行。
//#ifdef _DEBUG
//#define new DEBUG_NEW
//#endif// 5. 在调试内部版本中,此步骤将阻止应用程序使用与 GDI+ 不兼容的 DEBUG_NEW 分配器。
// 在 ChildView.cpp 中,向 Gdiplus 命名空间添加一个 using 指令。
using namespace Gdiplus;// 6. 将以下代码添加到 CChildView 类的构造函数和析构函数,以初始化和关闭 GDI+。CChildView::CChildView()
{// Initialize GDI+.GdiplusStartupInput gdiplusStartupInput;GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
}CChildView::~CChildView()
{// Shutdown GDI+.GdiplusShutdown(m_gdiplusToken);
}// 7. 实现 CChildView::DrawMandelbrot 方法。
// 此方法会将 Mandelbrot 分形绘制到指定的 Bitmap 对象。
// Draws the Mandelbrot fractal to the specified Bitmap object.
void CChildView::DrawMandelbrot(BitmapPtr pBitmap)
{if (pBitmap == NULL)return;// Get the size of the bitmap.const UINT width = pBitmap->GetWidth();const UINT height = pBitmap->GetHeight();// Return if either width or height is zero.if (width == 0 || height == 0)return;// Lock the bitmap into system memory.BitmapData bitmapData; Rect rectBmp(0, 0, width, height);pBitmap->LockBits(&rectBmp, ImageLockModeWrite, PixelFormat32bppRGB, &bitmapData);// Obtain a pointer to the bitmap bits.int* bits = reinterpret_cast<int*>(bitmapData.Scan0);// Real and imaginary bounds of the complex plane.double re_min = -2.1;double re_max = 1.0;double im_min = -1.3;double im_max = 1.3;// Factors for mapping from image coordinates to coordinates on the complex plane.double re_factor = (re_max - re_min) / (width - 1);double im_factor = (im_max - im_min) / (height - 1);// The maximum number of iterations to perform on each point.const UINT max_iterations = 1000;// Compute whether each point lies in the Mandelbrot set.for (UINT row = 0u; row < height; ++row){// Obtain a pointer to the bitmap bits for the current row.int *destPixel = bits + (row * width);// Convert from image coordinate to coordinate on the complex plane.double y0 = im_max - (row * im_factor);for (UINT col = 0u; col < width; ++col){// Convert from image coordinate to coordinate on the complex plane.double x0 = re_min + col * re_factor;double x = x0;double y = y0;UINT iter = 0;double x_sq, y_sq;while (iter < max_iterations && ((x_sq = x*x) + (y_sq = y*y) < 4)){double temp = x_sq - y_sq + x0;y = 2 * x * y + y0;x = temp;++iter;}// If the point is in the set (or approximately close to it), color// the pixel black.if(iter == max_iterations) { *destPixel = 0;}// Otherwise, select a color that is based on the current iteration.else{BYTE red = static_cast<BYTE>((iter % 64) * 4);*destPixel = red<<16;}// Move to the next point.++destPixel;}}// Unlock the bitmap from system memory.pBitmap->UnlockBits(&bitmapData);
}// 7. 实现 CChildView::OnPaint 方法。 此方法将调用 CChildView::DrawMandelbrot,
// 然后将 Bitmap 对象的内容复制到窗口。
void CChildView::OnPaint()
{CPaintDC dc(this); // device context for painting// Get the size of the client area of the window.RECT rc;GetClientRect(&rc);// Create a Bitmap object that has the width and height of // the client area.BitmapPtr pBitmap(new Bitmap(rc.right, rc.bottom));if (pBitmap != NULL){// Draw the Mandelbrot fractal to the bitmap.DrawMandelbrot(pBitmap);// Draw the bitmap to the client area.Graphics g(dc);g.DrawImage(pBitmap.get(), 0, 0);}
}
// 8. 通过生成并运行应用程序来验证其是否已成功更新。
下图显示了 Mandelbrot 应用程序的结果。

由于每个像素的计算成本很高,因此在总体计算完成之前,UI 线程无法处理其他消息。 这可能会降低应用程序的响应能力。 但是,可以通过从 UI 线程中移除工作来缓解此问题。
相关文章:
windows C++-移除界面工作线程(一)
本文档演示了如何使用并发运行时将 Microsoft 基础类 (MFC) 应用程序中由用户界面 (UI) 线程执行的工作移动到工作线程。 本文档还演示了如何提高冗长绘制操作的性能。 通过将阻塞性操作(例如,绘制)卸载到工作线程来从 UI 线程中移除工作&am…...
Qt小bug — LINK : fatal error LNK1158: 无法运行“rc.exe“
Qt小bug —— LINK :fatal error LNK1158:无法运行"rc.exe" 环境 Qt 5.14.2 MSVC 2015 x64 现象 解决 在电脑上找到rc.exe 和rcdll.dll (一般在C:\Program Files(x86)\Windows Kits*\bin\x64下面)拷贝到 C:\Qt\Qt5…...
c++小游戏
目录 狼人杀 走迷宫 炸弹人 贪吃蛇 飞翔的小鸟 跑酷 吃豆人 飞机大战 人生模拟器 坦克大战 修仙模拟器 搜集了一些小游戏,名字下是个人是个人喜欢度,可供参考~ 狼人杀 ❤❤❤❤ #include<bits/stdc.h> #include<cstdio> #incl…...
k8s为什么用Calico
Calico是一种开源的网络和安全解决方案,主要用于容器、虚拟机、宿主机之间的网络连接。 它支持Kubernetes、OpenShift、Docker EE、OpenStack等PaaS或IaaS平台,提供高效的网络通信和安全控制功能12。 Calico的核心组件包括Felix、etcd、BIRD等。F…...
HashMap 和 Hashtable 有什么区别?
HashMap和Hashtable都是Java中常用的存储键值对的集合类,它们都实现了Map接口,但二者之间存在一些显著的区别。以下是对HashMap和Hashtable区别的详细归纳: 一、线程安全性 HashMap:是非线程安全的,即多个线程可以同…...
【机器学习】深度学习、强化学习和深度强化学习?
深度学习、强化学习和深度强化学习是机器学习的三个重要子领域。它们有着各自独特的应用场景和研究目标,虽然都属于机器学习的范畴,但各自的实现方式和侧重点有所不同。 1. 深度学习(Deep Learning) 深度学习是一种基于神经网络的…...
fastadmin 多商户模式下侧边栏跳转路径BUG
记录:仅作自己项目记录,在一个域名下部署多套项目时,若不是多商户模式项目会出现跳转路径问题。 修改 \manystore\library\Auth.php 文件的 getSidebar 方法 // 1 改为: $v[url] isset($v[url]) && $v[url] ? $v[url]…...
java内置的四种函数式接口
供给型:Supplier 无入参,有返回值。 FunctionalInterface public interface Supplier<T> {T get();}消费型:Consumer 有入参,无返回值。 FunctionalInterface public interface Consumer<T> {void accept(T t);de…...
如何获取 uni-app 应用发布所需的证书、私钥与配置文件
引言 在开发和发布iOS应用时,开发者常常会面临一系列复杂的证书、私钥密码以及配置文件的管理问题。这些配置不仅影响到应用的开发调试,还决定了应用是否能够顺利通过审核并发布到App Store。对于使用uni-app进行开发的开发者来说,自动生成的…...
TCP网络通信——多线程
前面分别用多进程和多路复用完成了TCP网络通信,本文就来讲讲多线程的TCP通信。首先来了解一下线程的概念: 1、线程是进程的执行路线,它是进程内部的控制序列,或者说线程是进程的一部分(进程是一个资源单位,线程是执行单…...
【exp报错注入】
整数范围 最大整数 exp 函数介绍 报错盲注注入 payload分析 709C-ASCII 值就等于我们下面的 7091-1 ,C就是我们要猜的值,当我们猜测的值和ASCII码相等时,那么exp就不会出现报错,因为1-1还是等于709: 练习 id1 an…...
基于SpringBoot问卷调查系统小程序【附源码】
基于SpringBoot问卷调查系统小程序 效果如下: 管理员登录界面 管理员功能界面 调查人管理界面 问卷调查管理界面 问卷题目管理界面 用户登录界面 APP首页界面 公告信息界面 研究背景 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨&…...
LLM - 配置 GraphRAG + Ollama 服务 构建 中文知识图谱
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/142795151 免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。 GraphR…...
简单认识redis - 6 redis 存储速度快的原因
1基于内存存储 缓存(内存)读写速度很快,相比于磁盘存储的Mysql 省去了磁盘I/O的次数。 2.高效的数据结构 SDS动态字符串: 1.字符串长度处理:Redis获取字符串长度,时间复杂度为O(1),而C语言中&am…...
【Qt Quick】状态:State 使用
State 是 Qt Quick 中管理界面组件状态的关键工具。它允许我们定义组件的不同状态,并且在用户交互或事件发生时进行状态切换,从而实现属性、外观和行为的动态变化。通过使用 State,可以避免复杂的条件逻辑,使代码更加简洁和可维护…...
ICE/TURN/STUN/Coturn服务器搭建
ICE 当我们想要实现在公网环境下的语音/视频通话功能时,就需要用到ICE交互式连接建立。ICE不是一种协议,整合了 STUN 和 TURN 两种协议(用于 NAT 穿透)的框架。 ICE的主要目标是解决NAT(网络地址转换)穿越…...
ctf.bugku-eval
题目来源:eval - Bugku CTF 访问页面, 代码解释 <?phpinclude "flag.php"; //包含"flag.php"文件$a $_REQUEST[hello]; //从请求参数hello中获取值并赋给变量$a。 eval( "var_dump($a);"); //…...
Extreme Compression of Large Language Models via Additive Quantization阅读
文章目录 Abstract1. Introduction2. Background & Related Work2.1. LLM量化2.2. 最近邻搜索的量化 3.AQLM:Additive Quantization for LLMs3.1. 概述3.1.0 补充**步骤说明****举例说明** 3.2. 阶段1:代码的波束搜索3.3. 阶段2:码本更新3.4. 阶段3&…...
【虚拟化】内核级虚拟化技术KVM介绍,全/半虚拟化的区别,使用libvirt搭建虚拟化平台(go/java/c++)
【虚拟化】内核级虚拟化技术KVM介绍,全/半虚拟化的区别,使用libvirt搭建虚拟化平台(go/java/c) 文章目录 1、虚拟化技术分类与架构(KVM,Xen),全/半虚拟化的区别2、libvirt介绍3、使用…...
C++类成员变量的初始化
1、优先使用或{} 类的非静态数据成员在声明时,使用或{}进行初始化执行默认初始化,构造函数只处理一些特殊成员。 2、直接初始化 使用()进行初始化、new运算符和类构造函数的初始化列表。 3、拷贝初始化 使用进行初始化、函数传参、函数返回值。 隐式调用…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
