c语言中跨平台线程同步对象有哪些特性及使用方法?
摘要:知道 ACE 这个库的 cpper 绝对要暴露年龄了,在没有 c++11 的年代把模板玩出了花,有的人说这个库适合学习不适合做项目,那今天就来看看学院派的 ACE 是如何封装线程同步对象的,以及当平台不支
前言
ACE (Adaptive Communication Environment) 是早年间很火的一个 c++ 开源通讯框架,当时 c++ 的库比较少,以至于谈 c++ 网络通讯就绕不开 ACE,随着后来 boost::asio / libevent / libev … 等专门解决通讯框架的库像雨后春笋一样冒出来,ACE 就渐渐式微了。特别是它虽然号称是通讯框架,实则把各个平台的基础设施都封装了一个遍,导致想用其中一个部分,也牵一发而动全身的引入了一堆其它的不相关的部分,虽然用起来很爽,但是耦合度太强,学习曲线过于陡峭,以至于坊间流传一种说法:ACE 适合学习,不适合快速上手做项目。所以后来也就慢慢淡出了人们的视线,不过对于一个真的把它拿来学习的人来说,它的一些设计思想还是不错的,今天就以线程同步对象为例,说一下“史上最全”的 ACE 是怎么封装的,感兴趣的同学可以和标准库、boost 或任意什么跨平台库做个对比,看看它是否当得起这个称呼。
互斥量
互斥量主要就是指各种 mutex 了,依据 mutex 的各种特性,又细分为以下几类:
ACE_Thread_Mutex
这个主要是做进程内多线程同步的,底层类型为 ACE_thread_mutex_t,这个类型在不同平台上依赖的设施也不尽相同,可以列表如下:
平台/接口/设施
windows
unix like (pthread)
Solaris
VxWorks
unsupport
ACE_thread_mutex_t
CRITICAL_SECTION
pthread_mutex_t
mutex_t
SEM_ID
int
init
InitializeCriticalSection
pthread_mutex_init
mutex_init
semMCreate
n/a
acquire
EnterCriticalSection
pthread_mutex_lock
mutex_lock
semTake (..WAIT_FOREVER..)
n/a
acquire (..time..)
n/a
pthread_mutex_timedlock
n/a
semTake (..time..)
n/a
tryacquire
TryEnterCriticalSection
pthread_mutex_trylock
mutex_trylock
semTake (..NOWAIT..)
n/a
release
LeaveCriticalSection
pthread_mutex_unlock
mutex_unlock
semGive
n/a
remove
DeleteCriticalSection
pthread_mutex_destroy
mutex_destroy
semDelete
n/a
对于上面的表做个简单说明:
windows 上就是使用临界区来做线程级别的互斥量;
unix like 一般都支持 pthread,例如 AIX / HPUX / IRIX / LYNXOS / MACOSX / UNIXWARE / OPENBSD / FREEBSD ……,如果不支持 pthread,则不在此列;
Solaris 有自己的线程库,不使用 pthread;
VxWorks 实时操作系统只有一个进程,可以有多个线程 (任务),所以这里使用的是进程级别的同步对象来模拟,具体就是信号灯 (SEM_ID);
对于没有 mutex 支持的系统,使用 int 来定义类别,函数体留空来避免编译报错 (相当于不起作用)。
另外由于线程同步对象没有对读写做分离,所以 acquire_read / acquire_write / tryacquire_read / tryacquire_write 均使用默认的 acquire / tryacquire 来实现。带超时参数的 acquire 重载,在有些平台并不被支持,例如 windows 和 Solaris。
ACE_Recursive_Thread_Mutex
与 ACE_Thread_Mutex 相比,增加了已锁定线程再次加锁的能力 (递归进入不死锁)。
