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

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 应用程序的结果。 

a35a42fc7fc640e89adca095f1b1bd7a.png

由于每个像素的计算成本很高,因此在总体计算完成之前,UI 线程无法处理其他消息。 这可能会降低应用程序的响应能力。 但是,可以通过从 UI 线程中移除工作来缓解此问题。

相关文章:

windows C++-移除界面工作线程(一)

本文档演示了如何使用并发运行时将 Microsoft 基础类 (MFC) 应用程序中由用户界面 (UI) 线程执行的工作移动到工作线程。 本文档还演示了如何提高冗长绘制操作的性能。 通过将阻塞性操作&#xff08;例如&#xff0c;绘制&#xff09;卸载到工作线程来从 UI 线程中移除工作&am…...

Qt小bug — LINK : fatal error LNK1158: 无法运行“rc.exe“

Qt小bug —— LINK &#xff1a;fatal error LNK1158&#xff1a;无法运行"rc.exe" 环境 Qt 5.14.2 MSVC 2015 x64 现象 解决 在电脑上找到rc.exe 和rcdll.dll &#xff08;一般在C:\Program Files(x86)\Windows Kits*\bin\x64下面&#xff09;拷贝到 C:\Qt\Qt5…...

c++小游戏

目录 狼人杀 走迷宫 炸弹人 贪吃蛇 飞翔的小鸟 跑酷 吃豆人 飞机大战 人生模拟器 坦克大战 修仙模拟器 搜集了一些小游戏&#xff0c;名字下是个人是个人喜欢度&#xff0c;可供参考~ 狼人杀 ❤❤❤❤ #include<bits/stdc.h> #include<cstdio> #incl…...

k8s为什么用Calico

‌Calico是一种开源的网络和安全解决方案&#xff0c;主要用于容器、虚拟机、宿主机之间的网络连接。‌ 它支持Kubernetes、OpenShift、Docker EE、OpenStack等PaaS或IaaS平台&#xff0c;提供高效的网络通信和安全控制功能‌12。 Calico的核心组件包括Felix、etcd、BIRD等。F…...

HashMap 和 Hashtable 有什么区别?

HashMap和Hashtable都是Java中常用的存储键值对的集合类&#xff0c;它们都实现了Map接口&#xff0c;但二者之间存在一些显著的区别。以下是对HashMap和Hashtable区别的详细归纳&#xff1a; 一、线程安全性 HashMap&#xff1a;是非线程安全的&#xff0c;即多个线程可以同…...

【机器学习】深度学习、强化学习和深度强化学习?

深度学习、强化学习和深度强化学习是机器学习的三个重要子领域。它们有着各自独特的应用场景和研究目标&#xff0c;虽然都属于机器学习的范畴&#xff0c;但各自的实现方式和侧重点有所不同。 1. 深度学习&#xff08;Deep Learning&#xff09; 深度学习是一种基于神经网络的…...

fastadmin 多商户模式下侧边栏跳转路径BUG

记录&#xff1a;仅作自己项目记录&#xff0c;在一个域名下部署多套项目时&#xff0c;若不是多商户模式项目会出现跳转路径问题。 修改 \manystore\library\Auth.php 文件的 getSidebar 方法 // 1 改为&#xff1a; $v[url] isset($v[url]) && $v[url] ? $v[url]…...

java内置的四种函数式接口

供给型&#xff1a;Supplier 无入参&#xff0c;有返回值。 FunctionalInterface public interface Supplier<T> {T get();}消费型&#xff1a;Consumer 有入参&#xff0c;无返回值。 FunctionalInterface public interface Consumer<T> {void accept(T t);de…...

如何获取 uni-app 应用发布所需的证书、私钥与配置文件

引言 在开发和发布iOS应用时&#xff0c;开发者常常会面临一系列复杂的证书、私钥密码以及配置文件的管理问题。这些配置不仅影响到应用的开发调试&#xff0c;还决定了应用是否能够顺利通过审核并发布到App Store。对于使用uni-app进行开发的开发者来说&#xff0c;自动生成的…...

TCP网络通信——多线程

前面分别用多进程和多路复用完成了TCP网络通信&#xff0c;本文就来讲讲多线程的TCP通信。首先来了解一下线程的概念&#xff1a; 1、线程是进程的执行路线&#xff0c;它是进程内部的控制序列&#xff0c;或者说线程是进程的一部分(进程是一个资源单位&#xff0c;线程是执行单…...

【exp报错注入】

整数范围 最大整数 exp 函数介绍 报错盲注注入 payload分析 709C-ASCII 值就等于我们下面的 7091-1 &#xff0c;C就是我们要猜的值&#xff0c;当我们猜测的值和ASCII码相等时&#xff0c;那么exp就不会出现报错&#xff0c;因为1-1还是等于709&#xff1a; 练习 id1 an…...

基于SpringBoot问卷调查系统小程序【附源码】

基于SpringBoot问卷调查系统小程序 效果如下&#xff1a; 管理员登录界面 管理员功能界面 调查人管理界面 问卷调查管理界面 问卷题目管理界面 用户登录界面 APP首页界面 公告信息界面 研究背景 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&…...

LLM - 配置 GraphRAG + Ollama 服务 构建 中文知识图谱

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/142795151 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 GraphR…...

简单认识redis - 6 redis 存储速度快的原因

1基于内存存储 缓存&#xff08;内存&#xff09;读写速度很快&#xff0c;相比于磁盘存储的Mysql 省去了磁盘I/O的次数。 2.高效的数据结构 SDS动态字符串&#xff1a; 1.字符串长度处理&#xff1a;Redis获取字符串长度&#xff0c;时间复杂度为O(1)&#xff0c;而C语言中&am…...

【Qt Quick】状态:State 使用

State 是 Qt Quick 中管理界面组件状态的关键工具。它允许我们定义组件的不同状态&#xff0c;并且在用户交互或事件发生时进行状态切换&#xff0c;从而实现属性、外观和行为的动态变化。通过使用 State&#xff0c;可以避免复杂的条件逻辑&#xff0c;使代码更加简洁和可维护…...

ICE/TURN/STUN/Coturn服务器搭建

ICE 当我们想要实现在公网环境下的语音/视频通话功能时&#xff0c;就需要用到ICE交互式连接建立。ICE不是一种协议&#xff0c;整合了 STUN 和 TURN 两种协议&#xff08;用于 NAT 穿透&#xff09;的框架。 ICE的主要目标是解决NAT&#xff08;网络地址转换&#xff09;穿越…...

ctf.bugku-eval

题目来源&#xff1a;eval - Bugku CTF 访问页面&#xff0c; 代码解释 <?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&#xff1a;代码的波束搜索3.3. 阶段2&#xff1a;码本更新3.4. 阶段3&…...

【虚拟化】内核级虚拟化技术KVM介绍,全/半虚拟化的区别,使用libvirt搭建虚拟化平台(go/java/c++)

【虚拟化】内核级虚拟化技术KVM介绍&#xff0c;全/半虚拟化的区别&#xff0c;使用libvirt搭建虚拟化平台&#xff08;go/java/c&#xff09; 文章目录 1、虚拟化技术分类与架构&#xff08;KVM&#xff0c;Xen&#xff09;&#xff0c;全/半虚拟化的区别2、libvirt介绍3、使用…...

C++类成员变量的初始化

1、优先使用或{} 类的非静态数据成员在声明时&#xff0c;使用或{}进行初始化执行默认初始化&#xff0c;构造函数只处理一些特殊成员。 2、直接初始化 使用()进行初始化、new运算符和类构造函数的初始化列表。 3、拷贝初始化 使用进行初始化、函数传参、函数返回值。 隐式调用…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...

安卓基础(Java 和 Gradle 版本)

1. 设置项目的 JDK 版本 方法1&#xff1a;通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分&#xff0c;设置 Gradle JDK 方法2&#xff1a;通过 Settings File → Settings... (或 CtrlAltS)…...