window核心编程-内核对象线程同步

Windows内核--任务、进程和线程(2.4) Windows内核有"任务"概念吗? 从技术术语来说,Windows内核并没有"任务"。"任务"一般被认为是抽象的需要执行的事情。在不同操作系统上,"任务"所代表的官方名称有所差异。 阅读详情

window核心编程-内核对象线程同步

1、内核对象线程同步介绍
上一章讲了关键字(临界区)线程同步,使用关键字线程同步,我们很容易陷入死锁的情形,这是因为我们无法为进入关键段指定一个最长等待时间。

本章将讨论如何使用内核对象来对线程同步。我们也将看到,与用户模式下的同步机制(关键段同步)相比,内核对象的用途要广泛的多。实际上,内核对象唯一的缺点就是它们的性能。内核对象包括进程、线程以及作业,几乎所有这些内核对象都可以用来进行同步。对线程同步来书,这些内核对象中的每一种要么处于触发状态,要么处于未触发状态。Microsoft为每种对象创建了一些规则,规定如何在这两种状态之间进行转换。例如,进程内核对象在创建的时候总是处于未触发状态。当进程终止的时候,操作系统会自动使进程内核对象变成触发状态。当进程内核对象被触发后,它将永远保持这种状态,再也不会变回到未触发状态。在进程内核对象的内部有一个布尔变量,当系统创建内核对象的时候会把这个变量的值初始化为false(未触发)。当进程终止的时候,操作系统会自动把相应的内核对象中的这个布尔值设为true,表示该对象已经被触发。


下边讲一些内核同步中用到的函数。
等该函数使一个线程自愿进入等待状态,直到指定的内核对象被触发为止。

DWORD waitForSingleObject(HANDLE hObject, DWORD dwMilliseconds);
//hObject:内核对象句柄
//dwMilliseconds等待时间ms为单位,INFINITE为一直等待,只到内核对象被触发为止。

DWORD WaitForMultipleObjects( DWORD nCount, CONST HANDLE *lpHandles, BOOL bWaitAll, DWORD dwMilliseconds );
//waitForSingleObject和WaitForMultipleObjects相似,唯一的不同之处在于它允许调用线程同时检查多个内核对象的触发状态

/*函数的返回值告诉调用方函数为什么它得以继续运行。如果给bWaitAll传的是FALSE,那么只要任何一个对象被触发,函数就会立即返回。这时的返回值是WAIT_OBJECT_0和(WAIT_OBJECT_0+dwCount-1)之间的任何一个值。换句话说,如果返回值既不是WAIT_TIMEOUT,也不是WAIT_FAILED,那么我们应该把返回值减去WAIT_OBJECT_0。得到的数值是我们在第二个参数中传的句柄数组的一个索引,用来告诉我们被触发的是那个对象。*/


//下面的事例代码可以更清晰的对此进行解释
HANDLE h[3];//我的博客:http://blog.youkuaiyun.com/windows_nt
h[0] = hProcess1;
h[1] = hProcess2;
h[2] = hProcess3;
DWORD dw = WaitForMultipleObjects(3, h, FALSE, 5000);
switch(dw)
{
case WAIT_FAILED:
	//Bad call to function (invalid handle)
	break;
case WAIT_TIMEOUT:
	//None of the objects became signaled within 5000 milliseconds
	break;
case WAIT_OBJECT_0 + 0:
	//h[0] signaled, hProcess1 terminated
	break;
case WAIT_OBJECT_0 + 1:
	//h[1] signaled, hProcess2 terminated
	break;
case WAIT_OBJECT_0 + 2:
	//h[2] signaled, hProcess3 terminated
	break;
}

2、事件内核对象
//事件包含一个使用计数(这一点和所有其他内核对象一样),一个用来表示事件是自动重置事件还是手动重置事件的布尔值,以及另一个用来表示事件有没有被触发的布尔值。
//有两种不同类型的事件对象:手动重置事件和自动重置事件。当一个手动重置事件被触发的时候,正在等待该事件的所有线程都将变成可调度状态,而当一个自动重置事件被触发的时候,只有一个正在等待该事件的线程会变成可调用状态。


//创建一个事件内核对象
HANDLE CreateEvent( 
LPSECURITY_ATTRIBUTES lpEventAttributes, //安全属性
BOOL bManualReset, //自动重置/手动重置
BOOL bInitialState, //是否触发

LPCSTR lpName );//事件内核对象的名字,可以为空

//新版本

HANDLE CreateEventEx(
LPSECURITY_ATTRIBUTES psa, //安全属性
PCTSTR pszName, //名字
DWORD dwFlags, //是否触发

DWORD dwDesiredAccess)

//dwDesiredAccess:允许我们指定在创建事件时返回的句柄对事件有何种访问权限。这是一种创建事件句柄的新方法,它可以减少权限,相比较而言,CreateEvent()总是被授予全部权限。但CreateEventEx()更有用的地方在于它允许我们以减少权限的方式来打开一个已经存在的事件,而CreateEvent()总是要求全部权限。


//下边这个例子展示了如何使用事件内核对象来对线程进行同步。
//Create a global handle to a manual-reset, nonsignaled event.
HANDLE g_hEvent;
int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, 
					 LPSTR lpCmdLine, int nShowCmd )
{
	//Create the manual-reset, nonsignaled event
	g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	//Spawn 3 new threads
	HANDLE hThread[3];
	DWORD dwThread;
	hThread[0] = _beginthread(NULL, 0, wordCount, NULL, 0, &dwThread);
	hThread[1] = _beginthread(NULL, 0, SpellCheck, NULL, 0, &dwThread);
	hThread[2] = _beginthread(NULL, 0, GrammarCheck, NULL, 0, &dwThread);


	OpenFileAndReadContentsIntoMemory(...);
	//allow all 3 threads to access the memory
	SetEvent(g_hEvent);
}


DWORD WINAPI wordCount(PVOID pvParam)
{
	//Wait until the file's data is in memory
	waitForSingleObject(g_hEvent, INFINITE);
	//access the memory block.
	return 0;
}


DWORD WINAPI SpellCheck(PVOID pvParam)
{
	//Wait until the file's data is in memory
	waitForSingleObject(g_hEvent, INFINITE);
	//access the memory block.
	return 0;
}


DWORD WINAPI GrammarCheck(PVOID pvParam)
{
	//Wait until the file's data is in memory
	waitForSingleObject(g_hEvent, INFINITE);
	//access the memory block.
	return 0;
}

下边是我自己写的一个事例片段,很简单

CString strName = _T("");

UINT CBcgTestDlg::ThreadWorkFunc(LPVOID lPvoid)
{
	
	for (int n = 0; n < 10000; n++)
	{
		strName = _T("http://blog.youkuaiyun.com/windows_nt");
		strName = strName + _T("\n");
		TRACE(strName);
	}
	
	return 0;
}

void CBcgTestDlg::OnOK() 
{
	CWinThread* pThread = NULL;

	for (int n = 0; n < 10000; ++n)
	{
		if (pThread)
		{
			WaitForSingleObject(pThread->m_hThread, INFINITE);
			delete pThread;
		}
		
		pThread = AfxBeginThread(ThreadWorkFunc, NULL, 0, CREATE_SUSPENDED, NULL);
		if (pThread)
		{
			pThread->m_bAutoDelete = FALSE;
			pThread->ResumeThread();
		}
	}
}
注意线程函数可以为类函数,但必须是静态函数

3.Windows核心编程-线程及线程调度 线程 与进程类似,线程也由两个组件组成: 一个是线程的内核对象,操作系统用它管理线程。内核对象还是系统用来存放线程统计信息的地方; 一个线程堆栈,用于维护线程执行时所需的所有函数参数和局部变量。 //线程函数//创建线程 HANDLE CreateThread( PSECURITY_ATTRIBUTES psa, //线程安全属性 DWORD 阅读详情

相关推荐

XR Interaction Toolkit实战:为HTC Vive Cosmos打造抓取、投掷与UI交互(Unity 2023教程)

本文详细介绍了如何使用Unity 2023和XR Interaction Toolkit为HTC Vive Cosmos开发抓取、投掷与UI交互系统。通过实战案例'VR投掷训练室',从基础配置到高级功能实现,涵盖物理抓取、精准投掷机制和VR UI交互设计,帮助开发者提升VR交互开发技能。

weixin_30562507的博客 256

Windows操作系统管理进程和线程:内核模式和用户模式

根据前面的介绍,NT内核会把操作系统的代码和数据映射到系统中所有进程的内核空间中。这样,每个进程内的应用程序代码便可以很方便地调用内核空间中的系统服务。这里的“很方便”有多层含义,一方面是内核代码和用户代码在一个地址空间中,应用程序调用系统服务时不需要切换地址空间,另一方面是整个系统中内核空间的地址是统一的,编写内核空间的代码时会简单很多。但是,如此设计也带来一个很大的问题,那就是用户空间中的程序指针可以指向内核空间中的数据和代码,因此必须防止用户代码破坏内核空间中的操作系统。怎么做呢?答案是利用权限控制来

人邮异步社区 4459

[运营] ext4分区遇到“Structure needs cleaning”问题,怎么解决 - 结构需要清理

摘要:当ext4文件系统出现"Structure needs cleaning"错误时,表明存在元数据损坏。解决方法包括:1)检查系统日志确认错误;2)卸载受影响分区;3)使用fsck.ext4分步骤修复(先测试模式-n,再保守修复-p,严重损坏时用-y强制修复);4)检查修复结果;5)重新挂载。若数据丢失可尝试从lost+found恢复。建议定期备份、避免异常关机并定期检查文件系统,以防硬件故障导致类似问题。修复前务必备份重要数据。

Rudon滨海渔村的博客 1359

Windows核心编程 用内核对象进行线程同步

用户模式的线程同步机制: 优点:速度快,可保持在用户模式,无需切换到内核模式。 缺点:不适用于许多应用程序,不支持多个进程间的同步。 内核对象的唯一缺点就是性能:X86上,一个空的系统调用会占约200个CPU周期(原因是用户模式切换到内核模式时,伴随调度新线程而来的刷新高速缓存以及错过高速缓存(未命中))。         几乎所有的内核对象都可以进行线程同步。这些内核对象都包括两种状态:

fztfztfzt的专栏 1294

STM32+LoRa模块实战:从环境搭建到数据传输完整指南(附避坑清单)

本文提供STM32与LoRa模块从环境搭建到数据传输的完整实战指南,涵盖硬件连接、开发环境配置、AT指令设置、频段优化及低功耗设计等关键步骤,特别针对常见问题提供解决方案和避坑清单,助力物联网开发者高效实现远距离低功耗通信。

weixin_29168813的博客 290

ROS 2 + Astra Pro深度相机实战:5分钟搞定远程可视化与距离检测(附避坑指南)

本文提供了一份详尽的ROS 2与Astra Pro深度相机集成实战指南。通过5分钟快速部署,实现远程可视化与实时目标距离检测。文章涵盖驱动安装、SSH+X11远程调试、核心测距节点编写,并附有详细的避坑指南,帮助开发者高效构建机器人视觉感知系统。

weixin_29232507的博客 278

window驱动开发-内核线程

线程和工作项

王马的博客 1358

2026开源API网关横评:微服务与AI流量治理如何选型

API网关作为微服务架构的流量入口,承担着路由转发、安全管控、限流熔断等核心职责,是分布式系统治理的基础设施。随着大模型应用的普及,AI流量对网关提出了新的要求,如流式响应支持、Token级限流、多模型路由和成本分账等能力。传统网关通过插件拼凑AI功能,而AI原生网关则将这些能力内建。面对众多开源方案,如何根据业务场景做出合理选型?本文对Kong、APISIX、Higress、Envoy Gateway、MAI Gateway等主流开源API网关进行横向评测,从性能、动态性、K8s集成度、AI流量治理等维度

weixin_34242819的博客 482

多线程同步:互斥对象、事件对象、关键代码段

互斥对象、事件对象、关键代码段 一、互斥对象和事件对象属于内核对象,利用内核对象进行线程同步,速度较慢,但可以实现在多个进程中各线程间进行同步。 二、关键代码段式工作在用户方式下,同步速度较快,但在使用关键代码段时,很容易进入死锁状态,因为在进入关键代码时无法设定超时值。 MFC下In...

chuanzou4767的博客 185

用Python玩转共现分析:从NLTK到热力图可视化(附完整代码)

本文详细介绍了如何使用Python进行文本共现分析,从NLTK基础文本处理到构建共现矩阵,并实现热力图可视化。通过完整的代码示例,帮助数据分析师和开发者掌握这一揭示词语间关联网络的实用NLP技术,快速从文本中提取语义关系和主题结构。

weixin_29313817的博客 350

ThingsBoard移动应用详细讲解

ThingsBoard移动应用详细讲解

AldrichEugene 530

三种线程同步方式的比较

1、互斥对象和事件对象属于内核对象,利用内核对象进行线程同步,速度比较慢,但是利用内核对象,可以在多个进程的多个线程之间进行线程同步。2、关键代码段是工作在用户方式下,同步速度比较快,但容易产生死锁,因为在等待进入关键代码段时,无法设定超时值。一般在进行多线程编程时,首选关键代码段,如果在一个mfc程序中使用,可以在一个类的构造函数中调用InitializeCriticalSection函数,在这

孟源的专栏 2000

(九)DFI接口时序

文章目录一、DFI Interface 一、DFI Interface   DFI接口是连接DDR Controller与DDR_PHY之间的通用接口,其信号组如下表:       

Mr.翟的博客 1万+

windows核心编程之使用线程APC回调安全退出多个等待线程

前言 程序开发中经常遇到需要这些情况:辅助线程正在等待内核对象的触发,主线程需要强制终止辅助线程。我们常常做的就是使用:TerminateThread来强制终止线程。这样做当然是不太好的,强制终止线程后系统不会销毁此线程的堆栈,长久下去内存泄露问题就会很严重了。线程最安全的退出方式当然还是让它自己返回了。本文主要介绍windows核心编程中介绍的一种安全退出线程方式:使用可等待API等待内核对象

https://github.com/JelinYao 2859

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Window核心编程

Window核心编程 第一章:错误处理 FormatMessage/LocalLock\LocalFree 第二章: TEXT("..") TCHAR(CHAR,WCHAR)  安全字符串函数 (必须在包含其他所有文件之后才包含StrSafe.h) _tcscpy  _tcscpy_s _CrtSetReportMode(_CRT_ASSERT,0); //禁止可能由C运行时触发的所

零点起步 802

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

java ocx 线程_windows多线程同步互斥--总结

参考JustDoIT —— 大部分内容《Windows核心编程》线程同步对象速查表对象何时处于未触发状态何时处于触发状态WaitForSingleObject副作用内核对象自动重置事件ResetEvent,PulseEvent或者等待成功SetEvent,PulseEvent重置通知√手动重置事件ResetEvent,PulseEventSetEvent,PulseEvent没有√自动重置可等待计...

weixin_29239279的博客 159

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

windows 用内核对象进行线程同步

用内核对象进行线程同步 参考《Windows核心编程系列》谈谈用内核对象进行线程同步, 参考http://blog.youkuaiyun.com/shenzi/article/details/4609954 参考http://www.pinvoke.net/default.aspx/kernel32.openevent 一.创建事件       TCCASychronizedHandle = Cr

doxingg的专栏 853

(摘自windows核心编程之用内核对象进行线程同步)

信号量内核对象(Windows核心编程 p.251) 信号量内核对象用来对资源进行计数。包含一个使用计数,还包含另外两个32位值:一个最大资源计数和一个 当前资源计数。 创建信号量内核对象函数: HANDLE CreateSemaphore( PSECURITY_ATTRIBUTE psa, LONG lInitialCount, LONG lMaximumCount, P

pilqc2009的专栏 426

[笔记]Windows核心编程《二十》DLL的高级操作技术

文章目录前言一、DLL模块的显式加载和符号链接1.1 显式加载D L L模块1.2 显式卸载D L L模块1.3 显式链接到一个输出符号二、DLL的进入点函数2.1 DLL_PROCESS_ATTACH通知2.2 DLL_PROCESS_DETACH通知2.3 DLL_THREAD_ATTACH通知2.4 DLL_THREAD_DETACH通知2.5 顺序调用DllMain2.6 DllMain与C/C++运行期库三、延迟加载DLL四、函数转发器五、已知的DLL六、DLL转移七、改变模块的位置八、绑定模块总

二次元怪兽的博客 1446

【windows操作系统的同步机制】

最近看了下windows核心编程,虽然是比较老的书,但是感觉还是蛮有用的,顺便复习了一些操作系统的知识,比如本文的进程同步机制   用户模式下的线程同步   线程之间需要通信:   1.需要让多个线程同时访问一个共享资源,同时不能破坏资源的完整性   2.一个线程需要通知其他线程某项任务已经完成   方法一:原子访问:Interlocked系列函数   Interlocked...

dfy86404的博客 251

《谈谈Windows核心编程系列》导读

《谈谈Windows核心编程系列》导读         谈谈Windows核心编程系列终于发布完了。        发布这些文章的目的:          一是为了总结之用,当需要的时候可以迅速的找出。         二也是在记录学习轨迹。         慢慢的养成了一种习惯,好像不写笔记就不算读过书一样。读书的时候会不自觉的加快速度,有时候看的不是很仔细,有时甚至看了很多遍还是

ithzhang 1万+

WinCE 进程、线程和内存管理之同步

原文地址::http://blog.youkuaiyun.com/gooogleman/article/details/4376821 相关文章 1、WinCE多线程并发 同步安全不容忽视----http://tech.it168.com/a2009/1123/813/000000813789_all.shtml 在多数情况下,线程之间难免要相互通信、相互协调才能完成任务。比如,

xqhrs232的专栏 1124

多线程进程同步

windows线程同步分用户方式与内核方式用户方式:(效率相对较高)    1.原子锁    2.关键段(临界区)内核方式:    1.等待定时器    2.信号量    3.互斥对象(mutex)以下来自《windows核心编程》      持续更新中...

sinat_36391009的博客 319
上一篇: 结构体字节对齐
下一篇: 显示图片汇总
codinglf
博客等级 码龄16年 237粉丝 127原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值