临界区,互斥量,信号量,事件

临界区,互斥量,信号量,事件

四种进程或线程同步互斥的控制方法
1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。
2、互斥量:为协调共同对一个共享资源的单独访问而设计的。
3、信号量:为控制一个具有有限数量用户资源而设计。
4、事 件:用来通知线程有一些事件已发生,从而启动后继任务的开始。

临界区(Critical Section)

保证在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么 在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操 作共享资源的目的。
临界区包含两个操作原语:
EnterCriticalSection() 进入临界区
LeaveCriticalSection() 离开临界区
EnterCriticalSection() 语句执行后代码将进入临界区以后无论发生什么,必须确保与之匹配的 LeaveCriticalSection()都能够被执行到。否则临界区保护的共享资源将永远不会被释放。虽然临界区同步速度很快,但却只能用来同步本 进程内的线程,而不可用来同步多个进程中的线程。

互斥量(Mutex)

互斥量跟临界区很相似,只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一个,因此就决定了任何情况下此共享资源都不会同时被多个线程所访问。当前占据资源的线程在任务处理完后应将拥有的互斥对象交出,以便其他线程在获得后得以访问资源。互斥量比临界区复杂。因为使用互斥不仅仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享。

互斥量包含的几个操作原语:
CreateMutex() 创建一个互斥量
OpenMutex() 打开一个互斥量
ReleaseMutex() 释放互斥量
WaitForMultipleObjects() 等待互斥量对象

HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,    
                   BOOL bInitialOwner,    
                   LPCTSTR lpName ); 

参数 :
1)lpMutexAttributes 安全属性。NULL 表示使用默认的属性。这一指 定在 Windows 95 中无效。

2)bInitialOwner 如果你希望“调用 CreateMutex() 的这个线程” 拥有产生出来的 mutex,就将此值设为 TRUE 。

lpName mu tex 的名称(一个字符串)。任何进程或线程都 可以根据此名称使用这一 mutex。名称可以是任意 字符串,只要不含反斜线(backslash,\)即可。

信号量(Semaphores)

信号量对象对线程的同步方式与前面几种方法不同,信号允许多个线程同时使用共享资源 ,它指出了同时访问共享资源的线程最大数目。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。在用CreateSemaphore()创建信号量 时即要同时指出允许的最大资源计数和当前可用资源计数。一般是将当前可用资源计数设置为最大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数 就会减1,只要当前可用资源计数是大于0的,就可以发出信号量信号。但是当前可用计数减小到0时则说明当前占用资源的线程数已经达到了所允许的最大数目, 不能在允许其他线程的进入,此时的信号量信号将无法发出。线程在处理完共享资源后,应在离开的同时通过ReleaseSemaphore()函数将当前可 用资源计数加1。在任何时候当前可用资源计数决不可能大于最大资源计数。

信号量包含的几个操作原语:
CreateSemaphore() 创建一个信号量
OpenSemaphore() 打开一个信号量
ReleaseSemaphore() 释放信号量
WaitForSingleObject() 等待信号量

HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpAttributes,    
                       LONG lInitialCount,
                       LONG lMaximumCount,
                       LPCTSTR lpName ); 

参数 :

1)lpAttributes 安全属性。如果是 NULL 就表示要使用默认属 性。Windows 95 忽略这一参数。

2)lInitialCount semaphore 的初值。必须大于或等于 0,并且小于或等于lMaximumCount。

3)lMaximumCount Semaphore 的大值。这也就是在同一时间内能够 锁住 semaphore 之线程的多个数。

4)lpName Semaphore 的名称(一个字符串)。任何线程(或 进程)都可以根据这一名称引用到这个semaphore。这个值可以是 NULL ,意思是产生一 个没有名字的 semaphore

BOOL ReleaseSemaphore(HANDLE hSemaphore,
                      LONG lReleaseCount,
                      LPLONG lpPreviousCount ); 

参数 :

1)hSemaphore Semaphore 的 handle 。

2)lReleaseCount Semaphore 现值的增额。该值不可以是负值或 0。

3)lpPreviousCount 藉此传回 semaphore 原来的现值。

事件(Event)

事件对象也可以通过通知操作的方式来保持线程的同步。并且可以实现不同进程中的线程同步操作。
信号量包含的几个操作原语:
  CreateEvent() 创建一个事件
  OpenEvent() 打开一个事件
  SetEvent() 回置事件
  WaitForSingleObject() 等待一个事件

HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,     
                   BOOL bManualReset,    
                   BOOL bInitialState,     
                   LPCTSTR lpName ); 

参数 :

1)lpEventAttributes 安全属性。NULL 表示使用默认属性。该属性在 Windows 95 中会被忽略。

2)bManualReset 如为 FALSE,表示这个 event 将在变成激发状态 (因而唤醒一个线程)之后,自动重置(reset)为 非激发状态。如果是 TRUE,表示不会自动重置, 必须靠程序操作(调用 ResetEvent() )才能将激发 状态的 event 重置为非激发状态。

3)bInitialState 如为 TRUE ,表示这个 event 一开始处于激发状 态。如为 FALSE,则表示这个 event 一开始处于 非激发状态。

3)lpName Event 对象的名称。任何线程或进程都可以根据这 个文字名称,使用这一 event 对象。

总结:
1. 互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说它可以跨越进程使用。所以创建互斥量需要的资源更多,所以如果只为了在进程内部是用的话使用临界区会带来速度上的优势并能够减少资源占用量 。因为互斥量是跨进程的互斥量一旦被创建,就可以通过名字打开它。
2. 互斥量(Mutex),信号量(Semaphore),事件(Event)都可以被跨越进程使用来进行同步数据操作,而其他的对象与数据同步操作无关,但对于进程和线程来讲,如果进程和线程在运行状态则为无信号状态,在退出后为有信号状态。所以可以使用WaitForSingleObject来等待进程和 线程退出。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值