线程与内核对象的同步-2

简介:

等待定时器内核事件
CreateWaitableTimer(
PSECURITY_ATTRIBUTES psa,
BOOL fManualReset,
PCTSTR pszName);
进程可以获得它自己的与进程相关的现有等待定时器的句柄。
HANDLE OpenWaitableTimer(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
PCTSTR pszName);

等待定时器对象总是在未通知状态中创建,必须调用SetWaitableTimer函数来告诉定时器你想在何时让
它成为已通知态。
BOOL SetWaitableTimer(
HANDLE hTimer, //定时器
const LARGE_INTEGER *pDueTime, //pDueTime和lPeriod 一道使用,用于指明定时器何时应该第一次报时
LONG lPeriod,//指明定时器应该多长时间报时一次
PTIMERAPCROUTINE pfnCompletionRoutine,
PVOID pvArgToCompletionRoutine,
BOOL fResume);

FILETIME和LARGE_INTEGER
FILETIME 从32位的边界开始。
LARGE_INTEGER从64位边界开始。
系统移值要考虑对齐的问题。

让等待定时器给APC排队。

信标内核对象
如果当前资源数量大于0,则发出信标信号。
如果当前资源数量是0,则不发出信标信号。
系统绝不允许当前资源的数量为负值。
当前资源的数量决不能大于最大资源数量。
不要把信标的使用数量与它的当前资源数量混为一谈。
HANDLE CreateSemphore(
PSECURITY_ATTRIBUTE psa,
LONG lInitialCount,
LONG lMaximumCount,
PCTSTR pszName);

HANDLE OpenSemaphore(
DWORD fdwAccess,
BOOL bInHeritHandle,
PCTSTR pszName);

ReleaseSemaphore(
HANDLE hsem,
LONG lReleaseCount,
PLONG plPreviousCount)

信标能够以原子操作方式来执行测试和设置操作。 相当于relase 使数量+1,而成功地等待信标的副作用是它的数量递减 1

互斥对象内核对象
互斥对象包含一个使用数量,线程ID和一个递归计数器。
互斥对象比关键代码要慢(前者是内核对象)但可以跨进程

规则:
如果线程ID是0,互斥对象不被任何线程拥有,并发出该互斥对象的通知信号。
如果ID是一个非0数字,那么一个线程就拥有互斥对象,并且不发出该互斥对象的通知信号。
与所有其他内核对象不同,互斥对象在操作系统中拥有特殊的代码,允许它们违反正常规则。
HANDLE CreateMutex(
PSECURITY_ATTRIBUTES psa,
BOOL fInitialOwner,
PCTSTR pszName);
通过OpenMutex,另一个进程可以获得它自己进程与现有互斥对象相关的句柄
HANDLE OpenMutex(
DWORD fdwAccess,
BOOL bInheritHandle,
PCTSTR pszName);

fInitialOwner 控制互斥对象的初始状态,如果设为true,那么线程ID被设为调用线程ID,递归计数器被设1.
如果是false,线程ID和递归计数器都设置为0,这意味着互斥对象没有被任何线程所拥有,因此发出它的通知信号。

通过调用一个等待函数,并传递一个负责保护资源的互斥对象句柄,线程就能够获得对共享资源的访问权。
在内部,等待函数要检查线程的ID,以了解它是否是0,如果线程ID是0,那么该线程ID被设置为调用线程ID,
递归计数设置为1,同时,调用线程保持可调度状态。
如果等待函数发现ID不是0,那么调用线程进入等待状态,系统将记住这个情况,并且在互斥对象的ID重
置为0时,将线程ID设置为等待线程ID,将递归计数器设置为1,并且允许等待线程再次成为可调度线程。
检查和修改都是原子方式进行的。
特殊情况,一个线程试图等待一个未通知的互斥对象,系统查看申请线程ID和互斥对象中记录的线程ID
相同,即使互斥对象处于未通知态,系统也允许线程保持可调度状态。递归计数器加1.

BOOL RelaseMutex(HANDLE hUmtex);
递归计数器减一,当递归计数器为0,线程ID重置0,同时对象变为已通知状态。

释放的时候也要查看线程ID是否相同。
当释放对象之前,拥有互斥对象的线程被终止了,那么系统把该互斥对象视为已经被放弃,
重新初始化。
不同的是等待函数得到的返回值不是WAIT_OBJECT_0 而是,WAIT_ABANDONED.

 



本文转自莫水千流博客园博客,原文链接:http://www.cnblogs.com/zhoug2020/p/4263760.html,如需转载请自行联系原作者

相关文章
|
2月前
|
Java 开发者 C++
Java多线程同步大揭秘:synchronized与Lock的终极对决!
Java多线程同步大揭秘:synchronized与Lock的终极对决!
59 5
|
4月前
|
Java 开发者 C++
Java多线程同步大揭秘:synchronized与Lock的终极对决!
【6月更文挑战第20天】在Java多线程编程中,`synchronized`和`Lock`是两种关键的同步机制。`synchronized`作为内置关键字提供基础同步,简单但可能不够灵活;而`Lock`接口自Java 5引入,提供更复杂的控制和优化性能的选项。在低竞争场景下,`synchronized`性能可能更好,但在高并发或需要精细控制时,`Lock`(如`ReentrantLock`)更具优势。选择哪种取决于具体需求和场景,理解两者机制至关重要。
41 1
|
4月前
|
Java 测试技术
Java多线程同步实战:从synchronized到Lock的进化之路!
【6月更文挑战第20天】Java多线程同步始于`synchronized`关键字,保证单线程访问共享资源,但为应对复杂场景,`Lock`接口(如`ReentrantLock`)提供了更细粒度控制,包括可重入、公平性及中断等待。通过实战比较两者在高并发下的性能,了解其应用场景。不断学习如`Semaphore`等工具并实践,能提升多线程编程能力。从同步起点到专家之路,每次实战都是进步的阶梯。
46 0
|
4月前
|
Java 程序员
从0到1,手把手教你玩转Java多线程同步!
【6月更文挑战第20天】从0到1学Java多线程同步:理解线程同步关键,掌握`synchronized`用法,探索`Lock`接口,实战演练并进阶学习锁升级、`Condition`及死锁预防,成为多线程大师!
24 0
|
2月前
|
安全 Java 开发者
Java多线程同步:synchronized与Lock的“爱恨情仇”!
Java多线程同步:synchronized与Lock的“爱恨情仇”!
81 5
|
2月前
|
Java 程序员
从0到1,手把手教你玩转Java多线程同步!
从0到1,手把手教你玩转Java多线程同步!
23 3
|
2月前
|
Java 测试技术
Java多线程同步实战:从synchronized到Lock的进化之路!
Java多线程同步实战:从synchronized到Lock的进化之路!
86 1
|
2月前
|
存储 Java 开发者
HashMap线程安全问题大揭秘:ConcurrentHashMap、自定义同步,一文让你彻底解锁!
【8月更文挑战第24天】HashMap是Java集合框架中不可或缺的一部分,以其高效的键值对存储和快速访问能力广受开发者欢迎。本文深入探讨了HashMap在JDK 1.8后的底层结构——数组+链表+红黑树混合模式,这种设计既利用了数组的快速定位优势,又通过链表和红黑树有效解决了哈希冲突问题。数组作为基石,每个元素包含一个Node节点,通过next指针形成链表;当链表长度过长时,采用红黑树进行优化,显著提升性能。此外,还介绍了HashMap的扩容机制,确保即使在数据量增大时也能保持高效运作。通过示例代码展示如何使用HashMap进行基本操作,帮助理解其实现原理及应用场景。
34 1
|
2月前
|
Java 调度 开发者
Java并发编程:解锁多线程同步的奥秘
在Java的世界里,并发编程是提升应用性能的关键所在。本文将深入浅出地探讨Java中的并发工具和同步机制,带领读者从基础到进阶,逐步掌握多线程编程的核心技巧。通过实例演示,我们将一起探索如何在多线程环境下保持数据的一致性,以及如何有效利用线程池来管理资源。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你对Java并发编程有更深入的理解和应用。
|
3月前
|
安全 Java 程序员
Java 并发编程:解锁多线程同步的奥秘
【7月更文挑战第30天】在Java的世界里,并发编程是一块充满挑战的领域。它如同一位严苛的导师,要求我们深入理解其运作机制,才能驾驭多线程的力量。本文将带你探索Java并发编程的核心概念,包括线程同步与通信、锁机制、以及并发集合的使用。我们将通过实例代码,揭示如何在多线程环境中保持数据的一致性和完整性,确保你的应用程序既高效又稳定。准备好了吗?让我们一同踏上这段解锁Java并发之谜的旅程。
36 5