Ice源码分析笔记1--IceUtils

Ice 是Zero C的一个分布式框架, 利用corba的思想,加强和改善了corba。

本系列文章主要通过本人对其源码的分析来讲述Ice的工作原理。

Ice主要包括以下几个部分:

  Ice: Ice核心模块

  IceUtils: Utils工具模块

  IceGrid: Ice节点模块

  。。。

 

Ice是利用自己定义的中间语言然后编译成各种常用语言的网络操作方法,然后调用各自语言下层的模块来进行工作的,在这里我主要是以c++代码来学习的。

 

本文主要讲述IceUtils的各个工具类。

1. Shared.h Shared.cpp

class Shared主要完成了引用计数的功能,可以说是一个代码中绝大数类的Base类。

主要有以下方法:

__incRef(): 引用计数+1

__decRef(): 引用计数-1

__setNoDelete(bool b): 设置不删除,如果为true, 当引用计数为0时则不删除对象,否则则删除。默认为false。

 

class SimpleShared 是Non-Thread-Safed的, class Shared则是Thread-Safed,因为这个类的广泛性,因此性能很重要,会根据不同的os平台去做同步机制的优化,见Shared.cpp,不能做优化的是用IceUtils::Mutex这个class,等下会来介绍class Mutex。

 

2. Handle.h

class Handle使用了模板对所有引用计数类型对象(继承了class Shared)完成了句柄的功能, 类似于smart pointer,在构造函数中增加引用计数,在析构函数中减少引用计数,以防止内存泄露。

 

3. Lock.h

同步方面的锁和互斥量等原语主要运用了Scoped Lock技术,使用一个class Lock在智能管理,即在构造函数中lock,析构函数中unlock,并且用模板在编译器确定类型,而所有这些类型(可以是各种不同的原语锁,比如各种Mutex)都相当于必须都拥有lock和unlock方法。

同理class TryLock也是如此,主要管理了tryLock和unlock方法,tryLock是非阻塞的,lock是阻塞的。

 

4. Mutex.h

Mutex是个非递归互斥量,Windows下使用CriticalSection, Posix下使用pthread mutex。其中有个内部struct叫LockState,该struct是用来给firend class Cond用的,在posix下用来暴露出pthread mutex来给pthread condition使用,可以结合等下介绍的Cond来看。

 

5. Cond.h Cond.cpp

Cond是一个同步原语的条件变量的wrapper facade,主要有以下方法:

1. wait(): 无限阻塞等待某个条件变量被signal。

2. timedWait(): 定时阻塞等待某个条件变量被signal。

3. signal(): 激活一个等待某个条件变量的线程。

4. broadcast(): 激活所有等待某个条件变量的线程。

 

代码分析要点:

1. wait阻塞之前会自动释放锁,返回后会自动获得锁。

// Release before posting to avoid potential immediate
// context switch due to the mutex being locked.

代码中这句注释重复出现过很多次,这是在多线程编程中应该注意的一点,在这里我解释下:

先释放锁再post信号量,或者在条件变量中先释放锁再signal条件变量,以防止上下文切换导致的问题。

假如先先post/signal后释放锁,就有可能出现在这时候发生线程上下文切换到wait的线程,但是因为锁的原因wait之后无法自动获得锁。

这样导致需要再切换回来释放锁后wait的线程再切换才能获得锁。

 

windows:

通过IceUtils::Mutex::unlock(Lockstate &)和IceUtils::Mutex::lock(Lockstate &),wait之前会自动释放锁,之后会自动获得锁。

在windows中通过信号量和CriticalSection来模拟(vista之后用户模式下出现了同步原语Slim reader/writer锁和条件变量,这个地方可能未来是可以分windows版本优化的地方)。使用信号量_gate设为资源数1来控制preWait和signal/broadcast函数不能同时获得该资源,信号量_queue来控制线程等待和唤醒,blocked和unblocked来控制阻塞和以激活的线程数目,mutex _internal来保护blocked和unblocked。

 

posix:

在posix中使用Mutex::LockState来暴露出其内部的pthread mutex来执行pthread_cond_wait方法。所以通过dummy的IceUtils::Mutex::unlock(Lockstate &)和IceUtils::Mutex::lock(Lockstate &)方法暴露给LockState变量。

 

Monitor:

使用了monitor模式,在posa中有介绍的,这里的实现方法,主要是通过前面介绍的Scoped Lock实现的class Lock的虚锁(模板参数类型)来实现,所以monitor有lock(),unlock(), tryLock()等函数。并且自己也是个模板类,模板参数是mutex类型的。这样配合一个IceUtils::Cond在lock中wait,在unlock中signal/broadcast,这样就能智能对这些资源进行管理了,不会导致泄漏。

 

 

 

 

 

 

 

你可能感兴趣的:(windows,struct,Class,wrapper,Signal,代码分析)