您的位置:首页 > 编程语言

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

2014-06-18 16:31 423 查看
内核对象即可处于触发状态,也可以处于未触发状态:

<进程

<线程

<作业

<事件

<信号量

<互斥量

<可等待的计数器

<文件以及控制台的标准输入流/输出流/错误流

对于线程同步来说,这些内核对象要么处于触发(signaled),要么处于未触发(nonsignaled)

当线程正在等待的内核对象处于未触发的时候,线程不可调度。等待的内核对象被触发,线程就变成可调度状态。

9.1 等待函数:

等待函数使一个线程自愿进入等待状态,直到指定的内核对象被触发为止。注意,

如果线程在调用一个等待函数的时候,相应的内核对象已经处于触发状态,那么这个线程是不会进入等待状态的。

DWORD WaiForSingleObject(HANDLE hObject, DWORD dwMilliseconds)

当线程调用这个函数的时候,第一个参数hObject用来标识要等待的内核对象,这个内核对象可以处于触发状态或

非触发状态。第二个参数dwMilliseconds用来指定线程最多愿意花多长时间来等待对象被触发。

DWORD WaitForMultipleObjects(DWORD dwCount, CONST HANDLE* phObjects, BOOL bWaitAll, DWORD dwMilliseconds)

它允许调用线程同时检查多个内核对象的触发状态:

参数dwCount表示我们希望函数检查的内核对象的数量。

参数phObjects是一个指针,指向一个内核对象句柄的数组。

通过两种不同的方式来使用WaitForMultipleObjects:

一种是让线程进入等待状态直到指定内核对象中的一个被触发为止(参数bWaitALL,为FALSE)

另一种是让线程进入等待状态直到指定的内核对象全部被触发为止(参数bWaitALL,为TRUE)

9.6 互斥量内核对象:

互斥量内核对象包含一个使用计数、线程ID以及一个递归计数。

线程ID用来标识当前占用这个互斥量的是系统的那个线程,递归计数表示这个线程占用该互斥量的次数。

一般用来对多个线程访问的同一块内存进行保护。

互斥量的规则:

1.如果线程ID为0(无效线程ID),那么该互斥量不为任何线程所占用。处于触发状态。

2.如果线程ID为非零值,那么有一个线程已经占用了该互斥量,它处于未触发状态。

CreateMutex

函数功能:创建互斥量

HANDLE CreateMutex(

LPSECURITY_ATTRIBUTES lpMutexAttributes,

BOOL bInitialOwner,

LPCTSTR lpName

);

函数说明:

第一个参数表示安全控制,一般直接传入NULL。

第二个参数用来确定互斥量的初始拥有者:

如果传入TRUE表示互斥量对象内部会记录创建它的线程的线程ID号并将递归计数设置为1,

由于该线程ID非零,所以互斥量处于未触发状态。

如果传入FALSE,那么互斥量对象内部的线程ID号将设置为NULL,递归计数设置为0,

这意味互斥量不为任何线程占用,处于触发状态。

第三个参数用来设置互斥量的名称,在多个进程中的线程就是通过名称来确保它们访问的是同一个互斥量。

函数返回值:

成功返回一个表示互斥量的句柄,失败返回NULL。

为了获得对被保护资源的访问权,线程要调用一个等待函数并传入互斥量的句柄。在内部等待函数会检查

线程ID是否为0(0表示互斥量处于触发状态)。如果为0,那么函数就会把线程ID设置为调用线程的线程ID。

把递归数设为1,然后让调用线程继续执行。

如果等待函数检测到线程ID不为0(互斥量处于未触发状态),那么调用线程将进入等待状态。当另一个线程

将互斥量的线程ID设为0的时候,系统会记得有一个线程正在等待,于是它把线程ID设置为正在等待的那个线程

的线程ID,把递归数设为1,使正在等待的线程变成可调度状态。

一旦成功地等到了互斥量,线程就知道自己已经独占了对受保护资源的访问。任何试图获得对资源访问的线程

都将进入等待状态。当前占用访问权的线程不再需要访问资源的时候,它必须调用ReleaseMutex函数来释放互斥量。

1.互斥量是内核对象,它与关键段都有”线程所有权“所以不能用于线程同步。

2.互斥量能够用于多个进程间线程互斥问题,并且能够完美解决某进程意外终止所造成的“遗弃”问题。

Mutex本质是一把锁,提供对资源的独占访问,所以Mutex主要的作用是用于互斥。Mutex对象的值,只有

0和1两个值。这个两个值也分别代表了Mutex的两种状态。

值0表示锁定状态,当前对象被锁定。用户进程/线程如果试图Lock临界资源,则进入排队等待。

值1表示空闲状态,当前对象为空闲。用户进程/线程可以Lock临界资源,之后Mutex值减一变为零。

获取mutex的拥有权:(加锁)

使用WaitForSingleObject或WaitForMuitipleObjects函数。这些Wait函数对mutex所作的事情

类似于enterCriticalSection对CriticalSection做的事情。一旦没有任何线程拥有mutex,它就处于激发状态,

Wait函就会成功。

释放mutex的拥有权:(解锁)

获得mutex的线程调用ReleaseMutex,将之释放,使mutex处于激发状态。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: