windows核心编程--线程高级

Windows高级编程C#教程系列(1-6章) C#(读作“C Sharp”)是一种简单、现代、类型安全的面向对象的编程语言。它由微软公司开发,旨在与.NET Framework运行时环境配合使用。C# 结合了Visual Basic的快速开发能力和C++的强大功能,以其简洁、优雅和表达力强而闻名。在C#中,类是一种基本的面向对象编程的概念,用于定义对象的蓝图。通过类,我们可以创建具有相似特性的对象,这些对象被称为类的实例。下面的代码块展示了如何定义一个简单的类以及如何创建类的实例。set;set;// 构造函数Age = age; 阅读详情
暂停和恢复线程的运行

在 线程内核对象的内部有一个值,用于指明线程的暂停计数。当调用C r e a t e P r o c e s s或C r e a t e T h r e a d函数时,就创建了线程的内核对象,并且它的暂停计数被初始化为1。当线程的暂停计数是0的时候,除非线程正在等待其他某种事情的发生,否则该线程就处于 可调度状态。

恢复线程,可以用将调用R e s u m e T h r e a d
并将C r e a t e T h r e a d函数时返回的线程句柄传递给它(或者是将传递给C r e a t e P r o c e s s的p p i P r o c I n f o参数指向的线程句柄传递给它):

 

DWORD ResumeThread(HANDLE hThread);
当创建线程时,除了使用C R E AT E _ S U S P E N D E D外,也可以调用S u s p e n dT h r e a d函数来暂停线程的运行:

 

DWORD SuspendThread(HANDLE hThread);
暂停和恢复进程的运行

对 于Wi n d o w s来说,不存在暂停或恢复进程的概念,因为进程从来不会被安排获得C P U时间。Wi n d o w s确实允许一个进程暂停另一个进程中的所有线程的运行,但是从事暂停操作的进程必须是个调试程序。特别是,进程必须调用Wa i t F o r D e b u g E v e n t和C o n t i n u e D e b u g E v e n t之类的函数。
VOID SuspendProcess(DWORD dwProcessID, BOOL fSuspend)
{
   
//Get the list of threads in the system.

   HANDLE hSnapshot = CreateToolhelp32Snapshot(
      TH32CS_SNAPTHREAD, dwProcessID);

   
if(hSnapshot !=
 INVALID_HANDLE_VALUE) 
   
{
      
//Walk the list of threads.

      THREADENTRY32 te = { sizeof(te) };
      BOOL fOk 
= Thread32First(hSnapshot, &
te);

      
for(; fOk; fOk = Thread32Next(hSnapshot, &
te)) 
      
{
         
//Is this thread in the desired process?

         if(te.th32OwnerProcessID == dwProcessID) 
         
{
            
//Attempt to convert the thread ID into a handle.

            HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME,
               FALSE, te.th32ThreadID);

            
if(hThread !=
 NULL) 
            
{
               
//Suspend or resume the thread.

               if(fSuspend)
                  SuspendThread(hThread);
               
else

                  ResumeThread(hThread);
            }

            CloseHandle(hThread);
         }

      }

      CloseHandle(hSnapshot);
   }

}
以上是作者实现的,但是有的时候会出错.

 睡眠方式

线程也能告诉系统,它不想在某个时间段内被调度。这是通过调用S l e e p函数来实现的:

VOID Sleep(DWORD dwMilliseconds);
关于S l e e p函数,有下面几个重要问题值得注意:

• 调用S l e e p,可使线程自愿放弃它剩余的时间片。

• 系统将在大约的指定毫秒数内使线程不可调度。不错,如果告诉系统,想睡眠1 0 0 m s,那么可以睡眠大约这么长时间,但是也可能睡眠数秒钟或者数分钟。记住, Wi n d o w s不是个实时操作系统。虽然线程可能在规定的时间被唤醒,但是它能否做到,取决于系统中还有什么操作正在进行。

• 可以调用S l e e p,并且为d w M i l l i s e c o n d s参数传递I N F I N I T E。这将告诉系统永远不要调度该线程。这不是一件值得去做的事情。最好是让线程退出,并还原它的堆栈和内核对象。

• 可以将0传递给S l e e p。这将告诉系统,调用线程将释放剩余的时间片,并迫使系统调度另一个线程。但是,系统可以对刚刚调用S l e e p的线程重新调度。如果不存在多个拥有相同优先级的可调度线程,就会出现这种情况。

转换到另一个线程

系统提供了一个称为S w i t c h To T h r e a d的函数,使得另一个可调度线程(如果存在能够运行):

BOOL SwitchToThread();

当 调用这个函数的时候,系统要查看是否存在一个迫切需要C P U时间的线程。如果没有线程迫切需要C P U时间,S w i t c h To T h r e a d就会立即返回。如果存在一个迫切需要C P U时间的线程,S w i t c h To T h r e a d就对该线程进行调度(该线程的优先级可能低于调用S w i t c h To T h r e a d的线程)。

线程的运行时间

//Get the current time (start time).
DWORD dwStartTime = GetTickCount();

//
Perform complex algorithm here.

//Subtract start time from current time to get duration.

DWORD dwElapsedTime = GetTickCount() - dwStartTime;

这个代码做了一个简单的假设:即它不会被中断。但是,在抢占式操作系统中,永远无法知道线程何时被赋予C P U时间。



幸运的是,Wi n d o w s提供了一个称为G e t T h r e a d Ti m e s的函数,它能返回这些信息:

 

BOOL GetThreadTimes(HANDLE hThread,   PFILETIME pftCreationTime, PFILETIME pftExitTime,   PFILETIME pftKernelTime, PFILETIME pftUserTime);

使用实例

__int64 FileTimeToQuadWord(PFILETIME pft) 
{
   
return
 (Int64ShllMod32(
      pft
->dwHighDateTime, 32) | pft->
dwLowDateTime);
}


void PerformLongOperation() 
{
   FILETIME ftKernelTimeStart, ftKernelTimeEnd;
   FILETIME ftUserTimeStart,   ftUserTimeEnd;

   FILETIME ftDummy;
   __int64 qwKernelTimeElapsed, qwUserTimeElapsed,
      qwTotalTimeElapsed;

   
//Get starting times.

   GetThreadTimes(GetCurrentThread(), &ftDummy,
      
&ftDummy, &ftKernelTimeStart, &
ftUserTimeStart);

   
//
Perform complex algorithm here.

   
//Get ending times.

   GetThreadTimes(GetCurrentThread(), &ftDummy,
      
&ftDummy, &ftKernelTimeEnd, &
ftUserTimeEnd);

   
//
Get the elapsed kernel and user times by 
   
//
converting the start and end times 
   
//
from FILETIMEs to quad words, and then 
   
//subtract the start times from the end times.


   qwKernelTimeElapsed 
= 
      FileTimeToQuadWord(
&ftKernelTimeEnd) -

      FileTimeToQuadWord(
&ftKernelTimeStart);

   qwUserTimeElapsed 
=
 
      FileTimeToQuadWord(
&ftUserTimeEnd) -

      FileTimeToQuadWord(
&ftUserTimeStart);

   
//
Get total time duration by adding the kernel
   
//and user times.


   qwTotalTimeElapsed 
= qwKernelTimeElapsed + 
      qwUserTimeElapsed;

   
//
The total elapsed time is in 
   
//qwTotalTimeElapsed.

}

注意,G e t P r o c e s s Ti m e s是个类似G e t T h r e a d Ti m e s的函数,适用于进程中的所有线程:

BOOL GetProcessTimes(HANDLE hProcess,   PFILETIME pftCreationTime, PFILETIME pftExitTime,   PFILETIME pftKernelTime, PFILETIME pftUserTime);

对于高分辨率的配置文件来说, G e t T h r e a d Ti m e s并不完美。Wi n d o w s确实提供了一些高分辨率性能函数:

BOOL QueryPerformanceFrequency(   LARGE_INTEGER* pliFrequency);BOOL QueryPerformanceCounter(   LARGE_INTEGER* pliCount);

虽然这些函数认为,正在执行的线程并没有得到抢占的机会,但是高分辨率的配置文件是为短期存在的代码块设置的。为了使这些函数运行起来更加容易一些,我创建了下面这个C + +类:

class CStopwatch 
{
public
:
   CStopwatch() 
   
{ 
      QueryPerformanceFrequency(
&
m_liPerfFreq);
      Start();
   }


   
void Start() 
   
{ 
      QueryPerformanceCounter(
&
m_liPerfStart);
   }


   __int64 Now() 
const 
   
{
      
//
Returns # of milliseconds since
      
//Start was called


      LARGE_INTEGER liPerfNow;
      QueryPerformanceCounter(
&liPerfNow);

      
return (((liPerfNow.QuadPart -
 
         m_liPerfStart.QuadPart) 
* 1000)/

         m_liPerfFreq.QuadPart);
   }


private:

   
//Counts per second

   LARGE_INTEGER m_liPerfFreq;   

   
//Starting count

   LARGE_INTEGER m_liPerfStart;  
}
;

使用这个类如下:(这样的封装类很多的,我的blog有介绍)

//Create a stopwatch timer
//(which defaults to the current time).

CStopwatch stopwatch;

//
Execute the code I want to profile here.

//Get how much time has elapsed up to now.

  __int64 qwElapsedTime = stopwatch.Now();

//
qwElapsedTime indicates how long 
//
the profiled code executed in milliseconds.

运用结构环境(跟cpu的类型有关系)

环境结构使得系统能够记住线程的状态,这样,当下次线程拥有可以运行的C P U时,它就能够找到它上次中断运行的地方。

Wi n d o w s实际上允许查看线程内核对象的内部情况,以便抓取它当前的一组C P U寄存器。若要进行这项操作,只需要调用G e t T h r e a d C o n t e x t函数:

 

BOOL GetThreadContext(HANDLE hThread,   PCONTEXT pContext);

Wi n d o w s使你能够修改C O N T E X T结构中的成员,然后通过调用S e t T h r e a d C o n t e x t将新寄存器值放回线程的内核对象中:

 

BOOL SetThreadContext(HANDLE hThread,   CONST CONTEXT *pContext);

线程的优先级

若要设置和获得线程的相对优先级,必须调用下面的这些函数:

 

BOOL SetThreadPriority(HANDLE hThread,   int nPriority);

下面是检索线程的相对优先级的补充函数:

 

int GetThreadPriority(HANDLE hThread);



程序的优先级(进程的优先级)

下面是如何使一个进程将它自己的优先级类设置为空闲的例子:

 

BOOL SetPriorityClass(GetCurrentProcess(),   IDLE_PRIORITY_CLASS);

下面是用来检索进程的优先级类的补充函数:

 

DWORD GetPriorityClass(HANDLE hProcess);



动态提高线程的优先级等级

有些编程人员抱怨说,系统动态提高线程优先级等级的功能对他们的线程性能会产生一种不良的影响,为此M i c r o s o f t增加了下面两个函数,这样就能够使系统的动态提高线程优先级等级的功能不起作用:

 

BOOL SetProcessPriorityBoost(HANDLE hProcess,   BOOL DisablePriorityBoost);BOOL SetThreadPriorityBoost(HANDLE hThread,   BOOL DisablePriorityBoost);

这两个函数具有许多相似的共性,可以用来确定是激活还是停用优先级提高功能:

 

BOOL GetProcessPriorityBoost(HANDLE hProcess,   PBOOL pDisablePriorityBoost);BOOL GetThreadPriorityBoost(HANDLE hThread,   PBOOL pDisablePriorityBoost);


为前台进程调整调度程序(windows设置提供可以自定义优先执行application或后台的server)


Windows 2000实际上允许用户对这种调整进行相应的配置。在System Properties(系统属性)对话框的A d v a n c e d选项卡上,用户可以单击Performance Options(性能选项)按钮
 
智能制造 | 如何快速自动生成站位表及自动与BOM校验? 一、站位表(SMT行业中)是SMT上料防错的基础信息,用于对需上料物料与产线、贴片机位置、飞达规格型号、用量,建立基础资料。 SMT站位表是否正确? 首先需要人工确认站位表与SMT程序的是否符合,上料员依照站位表安装好后,确认人员需有第三方确认者 (品管确定)核对。 站位表内容包括什么? 站位表内容为:SMT站位号相对应的物料编码,元件位号,飞达大小/间距,数量等等,根据不同公司的要求而定义。 就目前来说,基本每一款贴片机都可以输出站位清单 但对于企业来说,直接输出的站位清单一般不直接使用,需要进行手动处理 阅读详情

相关推荐

如何编译RustDesk(Unbuntu 和Android版本)

备注:官方文档上,一边都是基于sciter,这个在后面已经不建议使用了,但是依然可以编译刚开始的时候看官方的文档,涉及的东西比较多,也搞的一头雾水,通过B站上一个视频,可以通过CI/CD来编译,以及act本地试试(最终放弃,大概需要下载大几十G的容器下来)。最终总算明确了方向,可以用自动化流水线来编译。直接看CI/CD的脚本文件文件在.github/workflows目录下,重点研究 bridge.yml 和flutter-build.yml 这两个文件。

lvronglee的专栏 2547

windows核心编程之线程暂停和恢复

每个线程都有一个线程内核对象,内核对象里包含各种信息 该对象里有一个暂停计数,当暂停计数大于0的时候,线程暂停 DWORD SuspendThread( HANDLE hThread //线程句柄 );//这个函数可以暂停线程,使得暂停计数加1 DWORD ResumeThread( HANDLE hThread // 线程句柄 );//这个函数使得线程的暂停计数减1,

baidu_25539425的博客 1605

从入门到精通:MediaGo跨平台部署全攻略,Docker+NAS实战案例深度拆解!

本篇将深入解析开源媒体处理工具MediaGo的运作机制,该软件具备跨平台兼容性,支持Windows、MacOS及Linux三大主流操作系统。其核心创新在于采用模块化架构设计,用户无需额外依赖任何插件即可完成快速部署。作为GitHub平台上的开源项目,该工具特别注重用户体验设计,通过Docker容器化方案可无缝接入各类网络存储设备,显著优化系统资源占用并提升数据处理效率。以飞牛云NAS系统为实施案例,本文将详细展示本地化部署全流程。

Yawesh的博客 1954

C++枚举线程方法

主要使用的下面几个函数: 1、CreateToolhelp32Snapshot 2、Thread32First 3、Thread32Next 所以要引用下面的头文件: #include 枚举线程的代码如下: // 枚举系统当前所有线程信息 // 并把信息输出到工程目录下EnumInfo_thread.txt BOOL EnumThreadInfo () { // 定义线程信息

钟斌的博客 4919

winedt + miktex + SumatraPDF 搭建latex环境

整个环境包含三部分: - winedt: 前端编辑器 - miktex: 后端编译器 - SumatraPDF: 预览器顺序无关紧要, 不过如果先装miktex的话, 可能会被winedt在安装的时候自动找到路径从而不需要设置.1.安装miktex首先在latex-project官网, 打开”get”后, 有四种平台: Linux, Mac OS, Windows, Online. 我写论文

Iteration makes perfection. 6463

机器人视觉实战:用OpenCV搞定手眼标定(附完整C++代码)

本文详细介绍了使用OpenCV实现机器人视觉中的手眼标定技术,包括核心算法、工业场景优化及完整C++代码示例。通过解析坐标系转换问题,提供从数据采集到标定验证的全流程解决方案,帮助开发者在复杂工业环境中实现高精度机械臂与视觉系统的协同作业。

weixin_29306571的博客 481

windows C++ 遍历进程线程以及进程加载的模块

本文是基于Win32 API函数实现遍历进程、遍历线程和遍历进程加载模块等获取系统信息的操作。

qq_43179054的博客 3010

SPICE仿真软件:PSpice_(10).噪声分析

噪声分析是电路设计和优化中的一个重要工具,特别是在低噪声放大器、传感器电路和通信电路中。通过准确设置噪声源和仿真参数,合理选择频率范围,并验证仿真结果,可以有效地评估和优化电路的噪声性能。PSpice提供的噪声分析功能强大且灵活,能够帮助工程师和研究人员在多种应用场景下进行详细的噪声分析。

kkchenjj的博客 1537

windows C++ 进程遍历、线程遍历模板。后附模板代码

进程遍历是windows软件必备需求,从安装到软件运行再到卸载我们或许都需要知道其他进程的信息。

Bobowen的博客 2688

基于OpenClaw的自动化文件管理与文档分类系统设计与实现

本文介绍了一种基于OpenClaw的自动化文件管理与文档分类系统。系统采用三层架构设计,包含数据层、逻辑层和应用层,核心组件涵盖文件扫描、处理、分类、移动等功能。技术选型上使用Python/FastAPI作为后端,结合PostgreSQL/Elasticsearch/MinIO存储方案,并整合scikit-learn/PyTorch等AI技术实现智能分类。系统实现了文件递归扫描、增量扫描、元数据提取等功能,通过文件哈希和修改时间检测变化。该方案能有效提升文件管理效率,实现文档的自动化分类与智能管理。

一键难忘的博客 755

大模型长对话中上下文无法承载全部历史,如何压缩或提取重点

如果说截断和滑动窗口是“硬性”压缩,那摘要生成技术就显得“软”多了,也更接近于智能化的解决方案。它的思路是:不直接丢弃历史,而是通过自然语言处理(NLP)技术,把冗长的对话记录浓缩成一段简短的摘要,保留核心信息。这样既能大幅减少token数量,又不至于丢失关键内容。这种方法通常会借助预训练模型,比如BART或T5,它们擅长从长文本中提取重点内容。

大模型大数据攻城狮的专栏 1588

Windows编程看什么书?

Windows 程序设计第5版上、下册   原书名: Programming Windows (Fifth Edition)   原出版社:Microsoft Press   作者:(美)Charles Petzold   译者:北京博彦科技发展有限责任公司   出版社:北京大学出版社   出版日期:2001-03   页码:1376   定价:160:00RMB   此书被认为是Windows编

ysw1234的专栏 2841

网规第三版:第4章网络资源设备(完结)

第 4 章 网络资源设备 调整内容: 更新主流网络设备(交换机、路由器、防火墙)的技术参数与选型标准 增加国产化网络设备与信创产品的相关内容 精简已淘汰的设备类型与技术指标

鹿鸣天涯 268

018_《Delphi下深入Windows核心编程》

本书是一本介绍Windows核心技术及高级技巧的专著。从系统内核编程出发,使用大量的例子帮助读者理解这些编程技术,讲述了线程同步及隐藏、系统钩子深入分析、读写物理磁盘的关键技术、读写物理内存和其他进程内存的核心技术、Windows 9x下调用16位实模式和保护模式代码的核心技术、直接读写端口技术、可执行文件加壳的技巧、PE结构分析、Ring0的实现、Windows API截取技术、屏幕取词技术等方面的内容。全书对热点源代码进行了深入剖析和讲解,同时本书汇聚了作者利用Soft-ICE跟踪调试经验,作者多年的编

敦格 3770

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Windows核心编程:用户模式下的线程同步

 作者:shenzi链接:http://blog.youkuaiyun.com/shenziWindows核心编程:用户模式下的线程同步     在以下两种基本情况下,线程之间需要相互通信: 需要让多个线程同时访问一个共享资源,同时不能破坏资源的完整性;一个线程需要通知其它线程某项任务已经完成。1.原子

shenzi的天空 2017

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

《Windows核心编程第五版》英文原版PDF资源介绍

《Windows核心编程第五版》英文原版PDF资源介绍 【下载地址】Windows核心编程第五版英文原版PDF资源介绍 《Windows核心编程第五版》是Windows平台编程的权威指南,英文原版PDF资源为您提供深入的学习体验。本书全面解析了Windows操作系统的核心机制,涵盖进程与线程管理、内存管理、文件系统操作、...

gitblog_06722的博客 521

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Windows核心编程学习文档

一、CreateProcess CreateProcess为启动进程函数:下面已启动NOTEPAD记事本进程为例阐述CreateProcess,函数的用法;   lpApplicationName:可执行文件的名称,(可不包含路径)。如果该参数为NULL,那必须 在参数lpCommandLine中传递文件名称。 lpCommandLine:传递给执行的文件的命令行参数。如果lpAppli

xlm289348的专栏 2797

Windows核心编程

Windows核心编程学习01.Winwods核心编程:字符和字符串处理02.Windows核心编程:内核对象03.Windows核心编程:进程04.Windows核心编程:线程基础05.Windows核心编程:作业06.Windows核心编程:线程调度07.

shenzi的天空 2567

[笔记]Windows核心编程《八》用内核对象进行线程同步

参考1 参考2 文章目录前言用户模式下的同步机制内核模式下的同步机制等待函数WatiForSingleObjectWaitForMultipleOBjecs例等待成功所引起的副作用事件内核对象CreateEvent函数CreatEventEx创建对象可等待的计时器内核对象信号量内核对象互斥量内核对象线程同步对象速查表其他的线程同步函数 前言 用户模式下的同步机制 用户模式下的同步机制的特点就是速度快,但也有些局限性, 例如, 对Interlocked系列函数只能戳一个值进行操作,它们从不会把线程切换到等待

二次元怪兽的博客 726

Windows编程的几本经典著作

Windows 程序设计(第5版): Programming Windows (Fifth Edition)作者:Charles Petzold此书被认为是Windows编程最好的导论性读本。在1994年5月,此书的作者Charles Petzold被《Window Magazine》和Microsoft公司授予”Windows Pioneer”奖,以表彰他对Microsoft Windows的成

china1000的专栏 1170

(C/C++)Windows编程

Windows编程的核心都在这里,带给你不同的体验

MOON_YZM的博客 3318
上一篇: windows核心编程--线程
下一篇: windows消息机制
strollerV
博客等级 码龄20年 13粉丝 89原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值