线程操作函数

线程的挂起和恢复

DWORD SuspendThread ( HANDLE hThread );   //挂起线程

DWORD ResumeThread ( HANDLE hThread );   //恢复线程

SuspendThread  ResumeThread 都返回之前的挂起计数。

一个线程最多可以挂起MAXIMUM_SUSPEND_COUNT (WinNT.h中定义为127次)。

 

进程的挂起和恢复

对于Windows来说,不存在暂停或恢复进程的概念,因为进程从来不会被安排获得cpu时间。

但是我们可以创建一个函数,用来挂起或者恢复进程中的全部线程,这样就能挂起或者恢复一个进程了。

参考代码如下:

#include <Windows.h>

#include <stdio.h>

#include <Tlhelp32.h>

//dwProcessID参数为需要挂起或者恢复的进程ID

// bSuspend参数如果为TRUE就挂起进程,否则恢复进程

void SuspendProcess(DWORD dwProcessID, BOOL bSuspend)

{

         HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessID);                    //获得系统内所以线程

         if (hSnapshot != INVALID_HANDLE_VALUE)

         {

                   THREADENTRY32 te;

                   ZeroMemory(&te, sizeof(te));

                   te.dwSize = sizeof(te);

 

                   BOOL bOK = Thread32First(hSnapshot, &te);  

                   for (; bOK; bOK = Thread32Next(hSnapshot, &te))

                   {

                            if (te.th32OwnerProcessID == dwProcessID)          //必须制定,否则程序会尝试挂起系统内所有的线程,就会导致死机

                            {

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

                                     if (hThread != NULL)

                                     {

                                               if (bSuspend)

                                               {

                                                        SuspendThread(hThread);

                                               }

                                               else

                                                        ResumeThread(hThread);

                                     }

                                     CloseHandle(hThread);

                            }

                   }

         }

         CloseHandle(hSnapshot);

}

int main(void)

{

         SuspendProcess(9636, FALSE);

         return 0;

}

 

睡眠

VOID Sleep (DWORD dwMilliseconds);

这个函数将使线程自己挂起 dwMilliseconds 长的时间。

1.       调用Sleep,可使线程自愿放弃它剩余的时间片。

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

3.可以调用Sleep,并且为dwMilliseconds参数传递INFINITE。这将告诉系统永远不要调度该线程。这不是一件值得去做的事情。最好是让线程退出,并还原它的堆栈和内核对象。

4. 可以将0传递给Sleep。这将告诉系统,调用线程将释放剩余的时间片,并迫使系统调度另一个线程。但是,系统可以对刚刚调用 Sleep的线程重新调度。Sleep(0)是指CPU交出当前线程的执行权,让CPU去执行其他线程。也就是放弃当前线程的时间片,转而执行其他线程

 

切换到另一个线程

BOOL SwitchToThread (void);

当调用这个函数的时候,系统要查看是否存在一个迫切需要CPU时间的线程。如果没有线程迫切需要CPU时间,SwitchToThread就会立即返回。如果存在一个迫切需要 CPU时间的线程,SwitchToThread就对该线程进行调度(该线程的优先级可能低于调用 SwitchToThread的线程)。

这个迫切需要CPU时间的线程可以运行一个时间段,然后系统调度程序照常运行。该函数允许一个需要资源的线程强制另一个优先级较低、而目前却拥有该资源的线程放弃该资源。如果调用 SwitchToThread函数时没有其他线程能够运行,那么该函数返回 FALSE,否则返回一个非0值。

Sleep():时间片只能让给优先级相同或更高的线程;

SwitchToThread():只要有可调度线程,即便优先级较低,也会让其调度。

 

在实际上下文中谈CONTEXT结构

CONTEXT结构包括以下部分:

   CONTEXT_CONTROL:包含CPU的控制寄存器,比如指今指针,堆栈指针,标志和函数返回地址..AX, BX, CX, DX, SI, D
     CONTEXT_INTEGER:用于标识CPU的整数寄存器.DS, ES, FS, GS
   CONTEXT_FLOATING_POINT:用于标识CPU的浮点寄存器.
     CONTEXT_SEGMENTS:用于标识CPU的段寄存器.SS:SP, CS:IP, FLAGS, BP
   CONTEXT_DEBUG_REGISTER:用于标识CPU的调试寄存器.  
   CONTEXT_EXTENDED_REGISTERS:用于标识CPU的扩展寄存器I
   CONTEXT_FULL:相当于CONTEXT_CONTROL or CONTEXT_INTEGER or   CONTEXT_SEGMENTS,即这三个标志的组合

 

 

我们可以使用GetThreadContext函数来查看线程内核对象的内部,并获取当前CPU寄存器状态的集合。

BOOL GetThreadContext (

HANDLE  hThread,

PCONTEXT  pContext)

若要调用该函数,只需指定一个CONTEXT结构,对某些标志(该结构的ContextFlags成员)进行初始化,指明想要收回哪些寄存器,并将该结构的地址传递给GetThreadContext 。然后该函数将数据填入你要求的成员。

在调用GetThreadContext函数之前,应该调用SuspendThread,否则,线程可能刚好被调度,这样一来,线程的上下文就和所获取的信息不一致了。

示例代码如下: 

         CONTEXT Context;                  //定义一个CONTEXT结构

 

         Context.ContextFlags = CONTEXT_CONTROL;    //告诉系统我们想获取线程控制寄存器的内容   

         GetThreadContext(hThread, &Context);      //调用GetThreadContext获取相关信息

Ps:在调用GetThreadContext函数之前,必须首先初始化CONTEXT结构的ContextFlags成员。

要获得线程的所有重要的寄存器(也就是微软认为最常用的寄存器),应该像下面一样初始化ContextFlags:

Context.ContextFlags = CONTEXT_FULL;

WinNT. h头文件中,定义了CONTEXT_FULLCONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS

 

当然,我们还可以通过调用SetThreadContext函数来改变结构中的成员,并把新的寄存器值放回线程的内核对象中

BOOL SetThreadContext (

HANDLE  hThread,

CONST CONTEXT  *pContext)

同样,如果要改变哪个线程的上下文,应该先暂停该线程。       

         CONTEXT Context;      //定义一个CONTEXT结构      

         SuspendThread(hThread);  //挂起线程  

         Context.ContextFlags = CONTEXT_CONTROL;   //获取当前上下文的值

         GetThreadContext(hThread, &Context);

 

         Context.Eip = 0x00010000;      //Eip字段存储的是指令指针,现在让指令指针指向地址 0x00010000;

         Context.ContextFlags = CONTEXT_CONTROL;

 

         SetThreadContext(hThread, &Context);   //重新设置线程上下文

 

         ResumeThread(hThread);         //恢复线程,现在线程开始从0x00010000这个地方开始执行指令

 

线程的优先级

优先级为0的线程:系统启动时,会创建一个优先级为0的“页面清零线程”,它只有在系统中没有其他可调度线程时,才能调度,用来清除内存中的闲置页面。

优先级在1 ~ 15之间的线程:一般用户模式下,线程的优先级都在该范围。

优先级在16 ~ 30之间的线程:一般是内核线程。

 

一旦进程运行,便可以通过调用SetPriorityClass来改变自己的优先级

BOOL SetPriorityClass(

         HANDLE  hProcess

         DWORD  fdwPriority);

用来获取进程优先级:

DWORD GetPriorityClass( HANDLE  hProcess );

 

设置和获取线程的相对优先级:

BOOL SetThreadPriority (

         HANDLE  hThread,

         Int  nPriority);

Int GetThreadPriority(HANDLE  hThread);

 

允许或者禁止进程或者线程动态提升自己的优先级:

BOOL SetProcessPriorityBoost(

         HANDLE  hProcess,

         BOOL  bDisablePriorityBoost);

 BOOL SetThreadPriorityBoost(

         HANDLE  hThread,

         BOOL  bDisablePriorityBoost);

 

判断当前是不是启用优先级提升:

BOOL GetProcessPriorityBoost(

         HANDLE  hProcess,

         PBOOL  pbDisablePriorityBoost);

 BOOL GetThreadPriorityBoost(

         HANDLE  hThread,

         PBOOL  pbDisablePriorityBoost);

 

在多CPU的情况下,我们可以限制某些线程只在可用的cpu的一个子集上运行:

BOOL SetProcessAffinityMask(

         HANDLE  hProcess

         DWORD_PTR  dwProcessAffinityMask);

第一个参数hProcess代表要设置的进程。第二个参数dwProcessAffinityMask是一个位掩码,代表线程可以在哪些CPU上运行。例如,传入0x00000005意味着这个进程中的线程可以在CPU 0 和 CPU 2上运行,但是不能在CPU 1 和 CPU 3~31上运行。

 

获取进程的关联性掩码:

BOOL GetProcessAffinityMask(

         HANDLE  hProcess

         PDWORD_PTR  pdwProcessAffinityMask,

PDWORD_PTR  pdwSystemAffinityMask);

设置线程的关联性掩码:

BOOL SetThreadAffinityMask(

         HANDLE  hThread

         DWORD_PTR  dwThreadAffinityMask);

 

有时候强制一个线程只是用特定的某个CPU并不是什么好主意。例如,如果有三个线程都只能使用CPU0,而CPU1,CPU2和CPU3却无所事事。我们想让一个线程运行在一个CPU上,但是同时系统也允许他移到另一个空闲的CPU,那就更好了。要给线程设置一个理想的CPU,可以调用如下:

DWORD SetThreadIdealProcessor(

         HANDLE  hThread,

         DWORD  dwIdealProcessor);

hThread用于指明要为哪个线程设置首选CPU。

dwIdealProcessor函数不是个位掩码,它是个从0到31/63,用于指明供线程希望使用的首选CPU 。可以传递一个MAXIMUM_PROCESSORS的值(在WinNT.h中定义,在32位操作系统中定义为32,64位操作系统中定义为64),表明线程没有理想的CPU。如果没有为该线程设置理想的CPU,那么该函数返回前一个理想的CPU或MAXIMUM_PROCESSORS。

转载于:https://www.cnblogs.com/fwycmengsoft/p/6158130.html

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

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

相关文章

先进激光三维成像雷达技术的研究进展与趋势分析

本文内容转载自《激光杂志》2019年第5期&#xff0c;版权归《激光杂志》编辑部所有。杨兴雨&#xff0c;李晨&#xff0c;郝丽婷&#xff0c;王元庆&#xff0c;古丽孜热∙艾尼外南京大学&#xff0c;伊犁师范学院摘要&#xff1a;激光雷达具有体积小、质量轻、探测距离远、高分…

android 时间控件使用,android 时间控件的使用

一、样式文件time.xmlandroid:orientation"vertical" android:layout_width"match_parent"android:layout_height"match_parent">android:layout_width"wrap_content"android:layout_height"wrap_content"android:id&quo…

python工具箱查询手册书籍京东_十二. 项目实战:爬取京东商城中的书籍信息

爬取网址&#xff1a;https://search.jd.com/Search?keywordpython爬取信息&#xff1a;书名&#xff0c;价格&#xff0c;出版社&#xff0c;日期爬取方式&#xff1a;scrapy框架 splash存储方式&#xff1a;csv页面如下&#xff0c;可以看到python相关的图书超过6000本。不…

Android Binder 系统学习笔记(一)Binder系统的基本使用方法

1.什么是RPC&#xff08;远程过程调用&#xff09; Binder系统的目的是实现远程过程调用&#xff08;RPC&#xff09;&#xff0c;即进程A去调用进程B的某个函数&#xff0c;它是在进程间通信&#xff08;IPC&#xff09;的基础上实现的。RPC的一个应用场景如下&#xff1a; A进…

mongodb 监听不到端口_干货|MongoDB简单操作和通过python进行操作

点击上方“AI遇见机器学习”&#xff0c;选择“星标”公众号重磅干货&#xff0c;第一时间送达这次我们主要来简单的讨论一下在MongoDB中如何更新数据(修改数据)&#xff0c;删除数据&#xff0c;以及如何通过Python调用MongoDB。一、简单使用MongoDB操作数据| a.更新数据| i.数…

人工智能+脑机接口:让我们距离“增强人类”越来越近

来源&#xff1a;资本实验室前段时间&#xff0c;一则新闻引发了广泛争议&#xff1a;国内一所小学利用头环来监控孩子的脑电波&#xff0c;以判断孩子上课是否走神。暂且不论该事件是否是一场打着高科技幌子的闹剧&#xff0c;头环本身所代表的脑机接口技术正在受到越来越多的…

oracle常见单词_Oracle中常见的英语单词

fatal&#xff1a;重要的&#xff0c;致命的。常见于[rootdido1 ~]# ps -ef|grep init.cssdroot 2918 1 0 09:59? 00:00:00 /bin/sh /etc/init.d/init.cssd fatal-------------------------dependencies&#xff1a;附属的diagnostic&#xff1a;诊断常见于[rootdido1 client]…

哲学的未来

来源&#xff1a;哲学园作者&#xff1a;约翰R塞尔译者&#xff1a;GTY约翰塞尔生于1932年&#xff0c;当代著名哲学家&#xff0c;现为美国加州大学伯克利分校Slusser哲学教授&#xff0c;在语言哲学、心灵哲学和社会哲学领域贡献巨大&#xff0c;是目前在世的最著名的分析哲学…

怎么知道wx.config执行成功没_作为一个减肥40斤,且10年没反弹的普通人,这份瘦身经验分享给你...

“减肥”是女生老生常谈的话题&#xff0c;但是“减肥失败”、“越减越肥”也是很多女生面临的常态。所以做为成功减肥40斤且10多年没有反弹的人&#xff0c;我想来给大家一些自己的经验。很多姑娘知道减肥的关键因素是“热量差”&#xff0c;无论是增加运动&#xff0c;还是减…

nodejs 笔记

安装环境----------------------------------------------------------------1,安装nodejs 起步----------------------------------------------------------------1,cd 进目录2,npm init3,安装模块browsersync模块 #npm install browser-syncbrowser-sync start --server --…

html代码type,HTML中type是什么意思

在HTML中&#xff0c;type是类型的意思&#xff0c;是一个标签属性&#xff0c;主要用于定义标签元素的类型或文档(脚本)的MIME类型&#xff1b;例在input标签中type属性可以规定input元素的类型&#xff0c;在script标签中type属性可以规定脚本的MIME类型。推荐&#xff1a;ht…

以图搜图 图像匹配_图像匹配,基于深度学习DenseNet实现以图搜图功能

原标题&#xff1a;图像匹配&#xff0c;基于深度学习DenseNet实现以图搜图功能度学习的发展使得在此之前以机器学习为主流算法的相关实现变得简单&#xff0c;而且准确率更高&#xff0c;效果更好&#xff0c;在图像检索这一块儿&#xff0c;目前有谷歌的以图搜图&#xff0c;…

bzoj1085骑士精神(搜索)

1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1893 Solved: 1051Description 在一个55的棋盘上有12个白色的骑士和12个黑色的骑士&#xff0c; 且有一个空位。在任何时候一个骑士都能按照骑士的走法&#xff08;它可以走到和它横坐标相差为1&am…

中国2项上榜:《时代周刊》2019年度100大最佳发明榜单发布!

来源&#xff1a;Time导读&#xff1a;《时代周刊》最新评选出2019年度100大最佳发明&#xff01;这100项突破性的发明改变了我们的生活、工作、娱乐和思考方式&#xff0c;它们让世界变得更美好&#xff0c;更智能&#xff0c;或更有趣。今天分享其中的20个极具未来感的产品。…

html异形轮播,异形滚动

异形滚动效果图.gif1、原理的揭示前言&#xff1a;图片大小处理问题的解决&#xff0c;当我们只改变盒子大小&#xff0c;图片会溢出&#xff0c;无法充满这个盒子。设置图片的宽高为 100%异形滚动.box {width: 100px;height: 100px;}img { //让图片充满整个盒子width: 100%;he…

python如何判断列表是否为空_Python中如何检查字符串/列表是否为空

本文最后更新于2018年5月5日&#xff0c;已超过 1 年没有更新&#xff0c;如果文章内容失效&#xff0c;还请反馈给我&#xff0c;谢谢&#xff01; Start 缘由&#xff1a; 整理、记录、备忘 正文&#xff1a; 参考解答&#xff1a; 从dict中取值时&#xff0c;一定要使用.get…

使用 jq 处理 json 文件的最佳实践

使用 jq 格式化 json 文本后再存入 json 文件&#xff0c;但不回显 json 内容 jq . << EOF > example.json [{"Classification": "hdfs-site","Properties": {"dfs.replication": "1"} }] EOF cat example.json使…

oracle19c 安装权限_Oracle19c 安装及SQL developer连接

因为偶然要用到Oracle数据库&#xff0c;而平常工作中用的都是mySQL的&#xff0c;所以电脑上安装的都是MySQL的相关服务&#xff0c;今天用到Oracle本地没有&#xff0c;所以自己安装了一个&#xff0c;但是因为不熟悉&#xff0c;安装遇到了很多的坑&#xff0c;因此记录一下…

【周末阅读】工业互联网的发展历程及实现路径

来源&#xff1a;青岛智能产业技术研究院【导读】目前&#xff0c;我国工业互联网发展迅猛&#xff0c;从国家层面、部委层面、地方层面都在积极推动&#xff0c;国际上对工业互联网发展也比较关注。我主要介绍工业互联网的三个方面内容&#xff1a;工业互联网的基本认识、国内…

三菱fx5u编程手册_FX5U系列PLC控制伺服3种方式

FX5U系列PLC为三菱目前最新的小型PLC&#xff0c;机身小巧却功能强大&#xff0c;不仅保留了三菱小型PLC已有的优点&#xff0c;还吸收了大型PLC的开发理念&#xff0c;在整体性能上得到了很大的提高。本文以FX5U在控制伺服的性能上做个总结&#xff0c;归纳下FX5U控制伺服的3种…