Netexpert FAQ 网络分析专家学习建议入口 @netexpert成员申请指南
网络分析时代 netexpert积分规则的说明 Netis招贤纳士(2008年11月22日更新)
发新话题
打印

信号量(一个延续了7年的低级编程问题)

信号量(一个延续了7年的低级编程问题)

最近(2006-10-12)才意识到一个延续了7年的低级编程问题。

信号量(sempahore)天然就是用于资源计数的。当一个进程试图控制并发线程数时,
首先就该想到用semaphore。但是,我这个蠢材,在7年前写这样一个程序的时候,居
然没有想到用semaphore,完全没有想到。当时光前进了7年后,我才"突然"意识到自
己之前有多蠢。

在Unix上我用了互斥锁与条件变量:

--------------------------------------------------------------------------
Pthread_mutex_lock( &allowcreatethread_mutex );
while ( threadnum >= maxthreadnum )
{
    Pthread_cond_wait( &allowcreatethread_cond, &allowcreatethread_mutex );
}  /* end of while */
threadnum++;
Pthread_mutex_unlock( &allowcreatethread_mutex );
/*
* 创建线程
*/
--------------------------------------------------------------------------
Pthread_mutex_lock( &allowcreatethread_mutex );
threadnum--;
Pthread_cond_broadcast( &allowcreatethread_cond );
Pthread_mutex_unlock( &allowcreatethread_mutex );
--------------------------------------------------------------------------

在Windows上我用了临界区与手工重置事件:

--------------------------------------------------------------------------
event   = CreateEvent
(
    NULL,
    TRUE,
    TRUE,
    NULL
);
if ( NULL == event )
{
    ... ...
}
EnterCriticalSection( &critical_section );
if ( threadnum >= maxthreadnum )
{
    ResetEvent( event );
}
LeaveCriticalSection( &critical_section );
if ( WAIT_FAILED == WaitForSingleObject( event, INFINITE ) )
{
    ... ...
}
EnterCriticalSection( &critical_section );
threadnum++;
LeaveCriticalSection( &critical_section );
/*
* 创建线程
*/
--------------------------------------------------------------------------
EnterCriticalSection( &critical_section );
threadnum--;
SetEvent( event );
LeaveCriticalSection( &critical_section );
--------------------------------------------------------------------------

我这不是吃撑了嘛,正经搞法分别应该如下:

--------------------------------------------------------------------------
sem_init
sem_wait

sem_post
--------------------------------------------------------------------------
CreateSemaphore
WaitForSingleObject

ReleaseSemaphore
--------------------------------------------------------------------------

鬼知道当年想什么去了。由于框架代码一直延续下来,结果我写的所有需要控制并发
线程数的程序都存在这个低级编程问题。最近自己反应过来后跟hume说起这个事,才
知道他以前查看我的一份源码时注意到我没有按常规思路使用semaphore,但他也只
是奇怪了一下下,没有提醒我,可恶啊,hume现在真的越来越不可靠了!
本帖最近评分记录
  • Vader 威望 +10 您的发言很有意义 2006-10-16 23:09
说了世上一无牵挂为何有悲喜
说了朋友相交如水为何重别离
说了少年笑看将来为何常回忆
说了青春一去无悔为何还哭泣

TOP

人脑袋有时候是会卡壳
你总是默默无语。看着你对我笑,其实我知道你也不快乐。你的眼睛,又快乐又悲哀!

TOP

偶也一直用criticalsection.................

TOP

查了查,发现criticalsection是效率最高的 大概消耗10个时间片
mutex和信号量效率比较低,因为是跨进程生效,消耗600个时间片级别

TOP

在Windows上我用了临界区与手工重置事件,有event的出现,你说的理由就不构成理由了。在能单一使用临界区的情况下才有效率上的意义。
说了世上一无牵挂为何有悲喜
说了朋友相交如水为何重别离
说了少年笑看将来为何常回忆
说了青春一去无悔为何还哭泣

TOP

Linux下不熟悉,win下面信号量互斥量会引起user-mode/kernel mode切换。

有时间我测一下,正好看到

TOP

引用:
原帖由 Vader 于 2006-11-16 12:44 发表
Linux下不熟悉,win下面信号量互斥量会引起user-mode/kernel mode切换。
我知道你意思啊,我回你的那句话也是针对Windows来的啊。我不是说了吗,只有单一用临界区才有这种效率上的意义,因为这是个纯用户态的同步对象。问题是现在要自己模拟信号量,已经引入了手工重置事件,event本身也是内核对象,此时是"临界区+手工重置事件"模拟"信号量",完全没有效率上的意义。

单一靠临界区是无法模拟信号量的,那样势必轮询,是对CPU的极大浪费。
说了世上一无牵挂为何有悲喜
说了朋友相交如水为何重别离
说了少年笑看将来为何常回忆
说了青春一去无悔为何还哭泣

TOP

发新话题
版块跳转