线程与内核对象的同步-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.

时间: 2024-10-13 00:45:23

线程与内核对象的同步-2的相关文章

线程与内核对象的同步

线程与内核对象的同步内核对象可以处于已通知或未通知状体进程,线程,作业,文件,控制台输入,文件修改,事件,可等待定时器 等待函数DWORD WaitForSingleObject(HANDLE hobject, DWORD dwMilliseconds); 同时查看若干个内核对象已通知状体DWORD WaitForMultipleObjects(DWORD dwCount,CONST HANDLE* phObjects,BOOL fWaitAll,DWORD dwMilliseconds);dw

Windows API学习---线程与内核对象的同步

前言 若干种内核对象,包括进程,线程和作业.可以将所有这些内核对象用于同步目的.对于线程同步来说,这些内核对象中的每种对象都可以说是处于已通知或未通知的状态之中.这种状态的切换是由Microsoft为每个对象建立的一套规则来决定的.例如,进程内核对象总是在未通知状态中创建的.当进程终止运行时,操作系统自动使该进程的内核对象处于已通知状态.一旦进程内核对象得到通知,它将永远保持这种状态,它的状态永远不会改为未通知状态. 当进程正在运行的时候,进程内核对象处于未通知状态,当进程终止运行的时候,它就变

java线程 在其他对象上同步、线程本地存储ThreadLocal:thinking in java4 21.3.6

package org.rui.thread.concurrency; /** * 在其他对象上同步 * synchronized 块必须给定一个在其上进行同步的对象,并且最合理的方式是,使用其方法正在被调用的当前对象 * :synchronized(this), 在 这种方式中,如果获得了synchronized块上的锁, * 那么该对象其他的synchronized方法和临界区就不能被调用了. * 因此,如果在this上同步,临界区的效果就会直接缩小在同步的范围内. * * 有时必须在另一个

内核对象&句柄

目录 1 内核对象的概念 2 内核对象的使用计数 3 句柄 4 句柄表 ??项目工程代码中设计句柄的使用,一时不知句柄是何物,通过查阅自学之后,对句柄及其使用有一个初步的了解.分享出来,算是抛砖引玉吧. ??在阐述句柄之前,先说明一下内核对象. 1 内核对象的概念 ??内核对象就是一个内存块,有内核分配,只能由内核访问. ??内存块是一种数据结构,其中的数据成员负责维护该对象的相应信息,这个数据结构以及其中的数据成员只能由内核访问,应用程序是无法访问到的,更别说修改其中的数据成员了. ??如何访

线程同步——内核对象实现线程同步——信号量

1 /* 2 3 信号量内核对象 4 信号量与其它内核量相同,包含一个使用计数,除此之外还包含两个量. 5 一个最大资源计数和一个当前资源计数. 6 信号量规则如下: 7 如果当前资源计数大于0,那么信号量处于触发状态. 8 如果当前资源计数等于0,那么信号量处于未触发状态. 9 系统绝不会让当前资源计数变为负数. 10 当前资源计数绝不会大于最大资源计数. 11 12 下面我们看一下信号量的创建函数 13 HANDLE CreateSemaphore( 14 LPSECURITY_ATTRIB

线程同步——内核对象实现线程同步——事件内核对象

1 事件内核对象 2 3 事件类型对象有两种不同类型,手动重置和自动重置 4 手动重置:当一个手动重置对象被触发时候,等待该对象的所有线程变为可调度. 5 自动重置:当一个自动重置对象被触发时,只有一个等待该事件的线程会变为可调度 6 7 下面是一个创建事件内核对象的函数: 8 HANDLE CreateEvent( 9 LPSECURITY_ATTRIBUTES lpEventAttributes, 10 BOOL bManualReset, 11 BOOL bInitialState, 12

线程同步——内核对象实现线程同步——可等待计时器内核对象

1 可等待计时器 2 可等待计时器是这样一种内核对象,他们会在某个指定的时间触发或每隔一段时间触发一次. 5 下面我们来介绍一下创建可等待计时器函数: 6 7 HANDLE CreateWaitableTimer( 8 LPSECURITY_ATTRIBUTES lpTimerAttributes, 9 BOOL bManualReset, 10 LPCSTR lpTimerName ); 11 第一.三个参数我想我也不用介绍了哈,这是创建内核对象基本都会有的参数. 12 第二个参数bManua

线程同步——内核对象实现线程同步——等待函数

1 对于内核对象实现线程同步,不得不提三点: 2 1)大多数内核对象既有触发也有未触发两个状态 3 比如:进程.线程.作业.文件流.事件.可等待的计时器.信号量.互斥量 4 2)等待函数:等待函数使线程自愿进入等待状态,直到指定的内核对象变为触发状态为止, 5 说道等待我们最喜欢不过了,因为这样不会浪费我们宝贵的CPU时间. 6 3)对于自动重置对象来说,当对象被触发时,函数会自动检测到(手动重置对象为触发是,函数也能检测到), 7 并开始执行,但是在函数会在返回之前使事件变为非触发状态. 8

Win32线程同步内核对象的比较

X86处理器上用户层到内核层的转换要花费600个CPU指令周期 临界区(关键代码段)不是内核对象 但当访问被占用的资源时会使用内核资源 功能同互斥但不可跨进程 (以上引用自:http://www.dewen.org/q/9561) WIN32内核对象都是由HANDLE操控 信号量(Semaphore) wait函数族使访问计数递减 当且仅当访问计数0时无信号 ReleaseSemaphore递增访问计数 互斥(Mutex) 有且仅有1个访问计数的信号量(二元信号量binary semaphore