Visual Studio 2022写Windows程序造成CPU占用率过高故障排除

news2024/11/16 0:41:39

 我是荔园微风,作为一名在IT界整整25年的老兵,今天针对Visual Studio 2022写Windows程序造成CPU占用率过高故障进行排除。

下面是一个标准的Windows程序,也可以说是经典程序了,但是这个程序一运行,WinMain.exe的CPU占用率接近100%,为什么会这样??这个时候一定要冷静,要好好回想windows程序的运行机制原理,知道原理了,吃透原理了,就能理解为什么会有这种故障现象,这对初学者要求较高,但这也是让初学者成长的最好的方法。

#include<windows.h>
#include<stdio.h>
 
LRESULT CALLBACK WinFirstProc(
  HWND hwnd,  // handle to window
  UINT uMsg,  // message identifier
  WPARAM wParam,  //first message parameter
  LPARAM lParam    //second message parameter
);
 
int WINAPI WinMain(
  HINSTANCE hInstance,  //handle to current instance
  HINSTANCE hPrevInstance,  // handle to previous instance
  LPSTR lpCmdLine,  //command line
  int nCmdShow  // show state
)
{
  //设计一个窗口类
  WNDCLASS wndcls;
  wndcls.cbClsExtra=0;
  wndcls.cbWndExtra=0;
  wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
  wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);
  wndcls.hIcon=LoadIcon(NULL, IDI_ERROR);
  wndcls.hInstance=hInstance;  //应用程序实例句柄由WinMain函数传进来
  wndcls.lpfnWndProc=WinFirstProc;
  wndcls.lpszClassName="csdn";
  wndcls.lpszMenuName=NULL;
  wndcls.style=CS_HREDRAW | CS_VREDRAW;
  RegisterClass(&wndcls);
  
   //创建窗口,定义一个变量用来保存成功创建窗口后返回的句柄
   HWND hwnd;
   hwnd=CreateWindow("csdn","www.csdn.net",WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,hInstance,NULL);
  
   //显示及刷新窗口
  ShowWindow(hwnd,SW_SHOWNORMAL);
  UpdateWindow(hwnd);
 
  //定义消息结构体,开始消息循环
  MSG msg;
  while(GetMessage(&msg,hwnd,0,0))
   {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
   }
  return msg.wParam;
}
 
   //编写窗口过程函数
  LRESULT CALLBACK WinFirstProc(
  HWND hwnd,  // handle to window
  UINT uMsg,  // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam  // second message parameter
)
{
  switch(uMsg)
   {
  case WM_CHAR:
      char szChar[20];
      sprintf_s(szChar, sizeof(szChar), "char is %d", wParam);
      MessageBox(hwnd, szChar, "char", 0);
      break;
  case WM_LBUTTONDOWN:
      MessageBox(hwnd,"mouse clicked","message",0);
      HDC hdc;
      hdc=GetDC(hwnd);  //不能在响应WM_PAINT消息时调用
      TextOut (hdc,0,50,"csdn", strlen("csdn"));
      ReleaseDC(hwnd, hdc);
      break;
  case WM_PAINT:
      HDC hDC;
      PAINTSTRUCT ps;
      hDC=BeginPaint(hwnd,&ps); //BeginPaint只能在响应WM_PAINT消息时调用 
        TextOut(hDC,0,0,"www.csdn.net",strlen("www.csdn.net"));
      EndPaint(hwnd, &ps);
      break;
  case WM_CLOSE:
      if (IDYES=MessageBox(hwnd,"是否结束? ", "message",MB_YESNO)
       {
          DestroyWindow(hwnd);
      }
      break;
  case WM_DESTROY:
       PostQuitMessage(0);
       break;
  default:
       return DefWindowProc(hwnd,uMsg, wParam,lParam);
  }
  return 0;
}

这个故障其实是一个消息循环的错误分析。解决的方法主要是,一方面你可以查CSDN,另一方面,你可以查MSDN,这两个地方查过了,问题基本就可以解决了。

注意下面这些代码中的第三行:

//定义消息结构体,开始消息循环
MSG msg;
while(GetMessage(&msg,hwnd,0,0))
{
   TranslateMessage(&msg);
  DispatchMessage(&msg);
}
return msg.wParam;

这段代码程序只有一个窗口,而我们前面说了 GetMessage函数的hWnd参数用于指定接收属于哪一个窗口的消息,于是上面程序就在消息循环中为 GetMessage函数的 hWnd参数指定了 CreateWindow函数返回的窗口句柄。如果这样,然后运行程序,再关闭程序。你会发现你的计算机变慢了,同时按下键盘上的“Ctrl+Alt+Delete”键,启动Windows的任务管理器,切换到“进程”选项卡,单击“CPU”项进行排序,你会发现WinMain.exe的CPU占用率非常高,那么这是什么原因呢?

在GetMessage函数中,曾说过如果hWnd参数是无效的窗口句柄或 lpMsg 参数是无效的指针,则 GetMessage 函数将返回-1。当我们关闭窗口时,调用了 DestroyWindow 来销毁窗口,由于窗口被销毁了,窗口的句柄当然也就是无效的句柄了,那么GetMessage将返回-1。在C/C++语言中,非0即为真,由于窗口被销毁,句柄变为无效,GetMessage总是返回-1,循环条件总是为真,于是形成了一个死循环,计算机当然就变慢了。

在 MSDN 关于 GetMessage函数的说明文档中给出了下面的代码:

BOOL bRet;

while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
   if (bRet == -1)
    {
      // handle the error and possibly exit
    } 
  else
  {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
  }
}

针对我们这个问题,可以修改上述代码如下:

HWND hwnd;
hwnd=CreateWindow(..);

…

MSG msg;
BOOL bRet;

while( (bRet = GetMessage( &msg, hwnd, 0, 0 )) != 0)
{
  if (bRet == -1)
  {
      // handle the error and possibly exit
      return -1;
   }
  else
  {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
  }
}

这样就可以排除这个故障了。

类似的各类故障还有很多很多,作为windows程序的初学者,一定不要怕这些故障,要多查CSDN,如果CSDN上没有相关的帖子,那就查MSDN,MSDN上也许不能像CSDN上这样直接给出答案,但是能让你从根本上来理解问题可能存在的地方。如果这样,我们就能通过解决一次故障而更深入的理解内部程序运行的机制,进而真正提高自己的真实水平。而这种水平的提升,是你在任何书本中都学不到的。根据我的经验,一个初学者如能用这个方法解决60至80个这样的同类问题,就能深入windows程序调试的理解,真正向高手前进了。

各位小伙伴,下次我们再深入研究windows程序的运行机制。

作者简介:荔园微风,1981年生,高级工程师,浙大工学硕士,软件工程项目主管,做过程序员、软件设计师、系统架构师,早期的Windows程序员,Visual Studio忠实用户,C/C++使用者,是一位在计算机界学习、拼搏、奋斗了25年的老将,经历了UNIX时代、桌面WIN32时代、Web应用时代、云计算时代、手机安卓时代、大数据时代、ICT时代、AI深度学习时代、智能机器时代,我不知道未来还会有什么时代,只记得这一路走来,充满着艰辛与收获,愿同大家一起走下去,充满希望的走下去。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/677206.html

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

相关文章

Android 13(T) - binder阅读(2)- ServiceManager的启动与获取

1 ServiceManager的启动 1.1 服务的启动与注册 上一篇笔记中有说到&#xff0c;ServiceManager是一个特殊的binder service&#xff0c;所以它和普通的service一样需要打开binder驱动&#xff0c;在驱动中创建一个属于ServiceManager进程的binder_proc。 int main(int argc,…

django中发送get post请求并获得数据

django中发送get post请求并获得数据 项目结构如下注册路由 urls.py在处理函数中处理请求 views.py进行 get的请求01浏览器 get请求传参数02服务器django get参数解析获取01浏览器 post的发送浏览器get 请求 获取页面返回的 form 发送post请求 带参数 02服务器django的post请求…

【Unity3D】平面光罩特效

1 前言 屏幕深度和法线纹理简介中对深度和法线纹理的来源、使用及推导过程进行了讲解&#xff0c;激光雷达特效中讲述了一种重构屏幕像素点世界坐标的方法&#xff0c;本文将沿用激光雷达特效中重构像素点世界坐标的方法&#xff0c;实现平面光罩特效。 假设平面光罩的高度为 s…

SpringCloud Alibaba入门7之引入服务网关Gateway

我们需要在客户端和服务端之间加一个统一的入口&#xff0c;来作为请求的统一接入&#xff0c;而在微服务的体系中&#xff0c;承担这个角色的就是网关。我们只需要将网关的机器IP配置到DNS,或者接入负载&#xff0c;那么客户端的服务最终通过我们的网关&#xff0c;再转发到对…

GEE:欧几里得距离——计算目标图像中每个像素到目标像素的距离

作者:CSDN @ _养乐多_ 利用欧几里得距离计算目标图像中每个像素到目标像素的距离,以量化像素与目标的接近程度。 结果如下图所示, 文章目录 一、欧几里得距离简介二、代码一、欧几里得距离简介 欧几里得距离(Euclidean distance)是在数学中常用的一种距离度量方式,用于…

Android PMS APP安装流程

仓库网址&#xff1a;http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java 一、PMS安装APP流程图 二、文件复制 PMS处理安装HandlerParams安装参数流程图 PackageManagerService.java#installStage…

职场求生记|唐朝打工人如何绝地求生

&#x1f4da;书名&#xff1a;《长安的荔枝》 ✏️作者&#xff1a;马伯庸 作为“见微”系列神作&#xff0c;其在微信读书总榜的第一名位置持续一段时间了&#xff0c;其讲述的内容和每个人都息息相关&#xff0c;更是能引起职场人的无限共鸣&#xff0c;值得深思。 ⭐故事…

使用networkx查看某一个节点的一阶/二阶/三阶邻居

文章目录 前言手动高级 前言 一般情况下&#xff0c;貌似这些图之类的包&#xff0c;只提供查询一个节点的一阶邻居&#xff0c;但是有的时候我们需要二阶甚至三阶&#xff0c;那么该如何做呢&#xff1f; 注意一下&#xff0c;本文的方法仅可以针对二阶或者三阶&#xff0c;…

一分钟 帮你搞懂什么是柔性数组!

文章目录 什么是柔性数组&#xff1f;柔性数组的特点柔性数组的使用模拟实现柔性数组的功能柔性数组的优势 什么是柔性数组&#xff1f; 柔性数组这个概念相信大多数人博友都没有听说过&#xff0c;但是它确实存在。 在C99中&#xff0c;结构&#xff08;结构体&#xff09;的…

【雕爷学编程】Arduino动手做(121)---夏普粉尘传感器模块

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

EMC学习笔记(十一)过孔

过孔 1.过孔模型1.1 过孔的数学模型1.2 对过孔模块的影响因素 2.过孔对信号传导与辐射发射影响2.2 过孔对阻抗控制的影响2.2 过孔数量对信号质量的影响 1.过孔模型 从过去设计的一些PCB板效果来看&#xff0c;过孔对于低频&#xff0c;低速信号的影响是很小的&#xff0c;但是…

Android 窗口实现原理

一、基本概念 1、窗口显示架构图 多窗口的核心原理其实就是分栈和设置栈边界2、Android的窗口分类 Android应用程序窗口,这个是最常见的&#xff08;拥有自己的WindowToken)譬如&#xff1a;Activity与Dialog Android应用程序子窗口&#xff08;必须依附到其他非子窗口才能存…

深度学习-第T11周——优化器对比实验

深度学习-第T11周——优化器对比实验 深度学习-第T11周——优化器对比实验一、前言二、我的环境三、前期工作1、导入数据集2、查看图片数目3、查看数据 四、数据预处理1、 加载数据1、设置图片格式2、划分训练集3、划分验证集4、查看标签 2、数据可视化3、检查数据4、配置数据集…

6月份读书学习好文记录

看看CHATGPT在最近几个月的发展趋势 https://blog.csdn.net/csdnnews/article/details/130878125?spm1000.2115.3001.5927 这是属于 AI 开发者的好时代&#xff0c;有什么理由不多去做一些尝试呢。 北大教授陈钟谈 AI 未来&#xff1a;逼近 AGI、融进元宇宙&#xff0c;开源…

06-浏览器渲染原理

什么是渲染&#xff1f; render&#xff0c;HTML字符串 --渲染--> 像素信息 URL地址是一个字符串&#xff0c;HTML、css、js都在里面 可以把渲染想象成一个函数&#xff0c;上代码&#xff1a; function render (html) {/* 第一行第二行*/return pixels; } 渲染时间点 …

【深入浅出 Spring Security(十二)】使用第三方(Github)授权登录

使用第三方&#xff08;Github&#xff09;授权登录 一、OAuth2 简单概述二、OAuth2 四种授权模式之授权码模式三、Github 授权登录准备工作创建 Spring Boot 项目Vue 测试代码测试效果 &#xff08;Github授权登录的具体操作在目录第三“章”&#xff09; 一、OAuth2 简单概述…

Spring Boot 优雅集成 Spring Security 5.7(安全框架)与 JWT(双令牌机制)

Spring Boot 集成 Spring Security &#xff08;安全框架&#xff09; 本章节将介绍 Spring Boot 集成 Spring Security 5.7&#xff08;安全框架&#xff09;。 &#x1f916; Spring Boot 2.x 实践案例&#xff08;代码仓库&#xff09; 介绍 Spring Security 是一个能够为基…

【CSDN创作纪念日】——博客小梦的“256”鸭~

博客小梦的创作纪念日&#x1f60e; 前言&#x1f64c;与CSDN的相遇浑水摸鱼的日常CSDN上的小小收获收获了 一群热爱编程&#xff0c;热爱创作的CSDN挚友创作上的小荣誉 憧憬未来 总结撒花&#x1f49e; &#x1f60e;博客昵称&#xff1a;博客小梦 &#x1f60a;最喜欢的座右铭…

【Spring】— Spring MVC简单数据绑定(一)

目录 Spring MVC数据绑定1.数据绑定概述2.简单数据绑定2.1 绑定默认数据类型2.2 绑定简单数据类型 Spring MVC数据绑定 1.数据绑定概述 在执行程序时&#xff0c;Spring MVC根据客户端请求参数的不同将请求消息中的信息以一定的方式转换并绑定到控制器类的方法参数中。这种将…

基于VMD-LSTM-IOWA-RBF的碳排放混合预测研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…