windows下mutex、Semaphore和CriticalSection用作锁时的性能对比!

160 views
Skip to first unread message

邱戈川

unread,
Feb 27, 2006, 3:33:44 AM2/27/06
to 基于ACE和SpiderMonkey的SMS虚拟运营系统
测试的方式:
long start = GetTickCount();
printf("Start Mutex Test from %ld\n", start);

for(int i=0; i<1000000; i++)
{
lock.Lock();
lock.Unlock();
}

long end = GetTickCount();
printf("Stop Mutex Test from %ld\n", end);

测试数据:用GetTickCount()得到:

Start Mutex Test from 14650984
Stop Mutex Test from 14655343
Start CriticalSection Test from 14655343
Stop CriticalSection Test from 14655359
Start Semaphore Test from 14655359
Stop Semaphore Test from 14659671

结论:window平台下:Semaphore
和Mutex性能差不多,但是CriticalSection性能最好(不到100ms),而且数量级都不一样(其他都在4s以上,而且高占用cpu)。

对于linux下和solaris的比较,请大家给出相应的数据。(好像没有CriticalSection)
如果测试方式不当,也请大家提出!

邱戈川

unread,
Feb 27, 2006, 3:49:32 AM2/27/06
to 基于ACE和SpiderMonkey的SMS虚拟运营系统
网上的讨论:

线程的同步机制:

1、 Event
用事件(Event)来同步线程是最具弹性的了。一个事件有两种状态:激发状态和未激发状态。也称有信号状态和无信号状态。事件又分两种类型:手动重置事件和自动重置事件。手动重置事件被设置为激发状态后,会唤醒所有等待的线程,而且一直保持为激发状态,直到程序重新把它设置为未激发状态。自动重置事件被设置为激发状态后,会唤醒“一个”等待中的线程,然后自动恢复为未激发状态。所以用自动重置事件来同步两个线程比较理想。MFC中对应的类为CEvent.。CEvent的构造函数默认创建一个自动重置的事件,而且处于未激发状态。共有三个函数来改变事件的状态:SetEvent,ResetEvent和PulseEvent。用事件来同步线程是一种比较理想的做法,但在实际的使用过程中要注意的是,对自动重置事件调用SetEvent和PulseEvent有可能会引起死锁,必须小心。

2、 Critical Section
使用临界区域的第一个忠告就是不要长时间锁住一份资源。这里的长时间是相对的,视不同程序而定。对一些控制软件来说,可能是数毫秒,但是对另外一些程序来说,可以长达数分钟。但进入临界区后必须尽快地离开,释放资源。如果不释放的话,会如何?答案是不会怎样。如果是主线程(GUI线程)要进入一个没有被释放的临界区,呵呵,程序就会挂了!临界区域的一个缺点就是:Critical
Section不是一个核心对象,无法获知进入临界区的线程是生是死,如果进入临界区的线程挂了,没有释放临界资源,系统无法获知,而且没有办法释放该临界资源。这个缺点在互斥器(Mutex)中得到了弥补。Critical
Section在MFC中的相应实现类是CcriticalSection。CcriticalSection::Lock()进入临界区,CcriticalSection::UnLock()离开临界区。

3、 Mutex
互斥器的功能和临界区域很相似。区别是:Mutex所花费的时间比Critical
Section多的多,但是Mutex是核心对象(Event、Semaphore也是),可以跨进程使用,而且等待一个被锁住的Mutex可以设定TIMEOUT,不会像Critical
Section那样无法得知临界区域的情况,而一直死等。MFC中的对应类为CMutex。Win32函数有:创建互斥体CreateMutex()
,打开互斥体OpenMutex(),释放互斥体ReleaseMutex()。Mutex的拥有权并非属于那个产生它的线程,而是最后那个对此Mutex进行等待操作(WaitForSingleObject等等)并且尚未进行ReleaseMutex()操作的线程。线程拥有Mutex就好像进入Critical
Section一样,一次只能有一个线程拥有该Mutex。如果一个拥有Mutex的线程在返回之前没有调用ReleaseMutex(),那么这个Mutex就被舍弃了,但是当其他线程等待(WaitForSingleObject等)这个Mutex时,仍能返回,并得到一个WAIT_ABANDONED_0返回值。能够知道一个Mutex被舍弃是Mutex特有的。

4、 Semaphore
信号量是最具历史的同步机制。信号量是解决producer/consumer问题的关键要素。对应的MFC类是Csemaphore。Win32函数CreateSemaphore()用来产生信号量。ReleaseSemaphore()用来解除锁定。Semaphore的现值代表的意义是目前可用的资源数,如果Semaphore的现值为1,表示还有一个锁定动作可以成功。如果现值为5,就表示还有五个锁定动作可以成功。当调用Wait…等函数要求锁定,如果Semaphore现值不为0,Wait…马上返回,资源数减1。当调用ReleaseSemaphore()资源数加1,当时不会超过初始设定的资源总数。

时代过客

unread,
Feb 27, 2006, 4:37:27 AM2/27/06
to 基于ACE和SpiderMonkey的SMS虚拟运营系统
CRITICALSECTION是OS在用户态实现的同步,而其它的是OS在内核态下实现的同步,后者的访问显然要更费CPU周期,后者有个好处就是能在多进程间进行线程同步,前者则不行

Diao Shengjie

unread,
Feb 27, 2006, 7:00:09 AM2/27/06
to ACE...@googlegroups.com
 
对象                    适用场合
 
CEvent                事件发生后才能访问资源;
Csemaphore        多个线程同时访问资源;
Cmutex               多个进城同时访问资源;
CriticalSection     只有一个应用程序访问资源;


 
2006/2/27, 时代过客 <practis...@163.com>:
CRITICALSECTION是OS在用户态实现的同步,而其它的是OS在内核态下实现的同步,后者的访问显然要更费CPU周期,后者有个好处就是能在多进程间进行线程同步,前者则不行

Diao Shengjie

unread,
Feb 27, 2006, 7:14:15 AM2/27/06
to ACE...@googlegroups.com

CriticalSection 容易进入死锁状态。

candid Qiu

unread,
Feb 27, 2006, 7:20:52 AM2/27/06
to ACE...@googlegroups.com
是么?举个例子,不然大家都不明白!

邱戈川

unread,
Feb 27, 2006, 7:23:12 AM2/27/06
to 基于ACE和SpiderMonkey的SMS虚拟运营系统
怎么没有人说说linux或solaris下的情况?

Diao Shengjie

unread,
Feb 27, 2006, 7:27:20 AM2/27/06
to ACE...@googlegroups.com
我这边没有环境, 再就是对linux下开发没有经验。

2006/2/27, 邱戈川 <can...@gmail.com>:
怎么没有人说说linux或solaris下的情况?

时代过客

unread,
Feb 27, 2006, 7:51:29 AM2/27/06
to 基于ACE和SpiderMonkey的SMS虚拟运营系统
Cmutex 多个进城同时访问资源;
================================
能同时访问??
不知道所指的资源是的同步对象还是之外的东西,如果是之外的东西,我就不同意
一个进程至少含有一个线程,而代码只能由线程来执行的

EVENT,MUTE,SEMAPHORE均为内核对象,在全局系统中只能存在由命名确实的唯一对象,通过这个命名,它们均可以在进程间共享同一个对象,因此它们在进程间进行线程同步.

Diao Shengjie

unread,
Feb 27, 2006, 8:16:48 AM2/27/06
to ACE...@googlegroups.com

有点含糊, 指的是线程同步对象。同CEvent 一样是内核对象。 我在实际应用中对Cutex的使用不是太多,可能是因为做过的程序不是太多。

 
2006/2/27, 时代过客 <practis...@163.com>:

Eric Wu

unread,
Feb 28, 2006, 9:04:09 AM2/28/06
to ACE...@googlegroups.com

Solaris下各个同步对象的基本用法和WINDOWS差异不大

 

但在嵌套LOCK方面有差异,好像Windows在嵌套LOCK时会挂住(记不太清楚是Windows还是Solaris)。


> From: can...@gmail.com
> To: ACE...@googlegroups.com
> Subject: Re: windows下mutex、Semaphore和CriticalSection用作锁时的性能对比!
> Date: Mon, 27 Feb 2006 12:23:12 +0000
>
> 怎么没有人说说linux或solaris下的情况?



Express yourself instantly with MSN Messenger! MSN Messenger
Reply all
Reply to author
Forward
0 new messages