并行处理之引用计数与状态的使用

--------------------------------------------------------------------------------
标题: 并行处理之引用计数与状态的使用
作者: 叶飞虎
日期: 2013.03.09
--------------------------------------------------------------------------------

    在并行处理过程中多线程对同一对象进行操作,而且操作各自独立,但又需要依赖对象
本身的状态,如已打开或已登录等等。这时需要给状态进行引用计数,以保证操作的有效和
并发性。

    为了便于描述, 以<远程文件系统>中的客户端连接对象类(TRFConnObj)中部分代码做为
示例:

// 对象状态
enum TObjState
        {osInactive        = 0,        // 未打开
         osClosing         = 1,        // 正在关闭
         osOpening         = 2,        // 正在打开
         osOpened          = 3};       // 已经打开

// 引用计数加 1
bool TRFConnObj::IncRefCount()
{
   // 初始化
   bool result = false;

   // 操作
   Lock();
   if (FState == osOpened)
   {
      FRefCount++;
      result = true;
   }
   Unlock();

   // 返回结果
   return result;
}

// 引用计数减 1
void TRFConnObj::DecRefCount()
{
   Lock();
   if (FRefCount > 0)
      FRefCount--;
   Unlock();
}

// 打开
long TRFConnObj::Open()
{
   // 初始化
   long  result   = crStateInvalid;
   bool  boolNext = false;

   // 更改状态
   Lock();
   if (FState == osInactive)
   {
      FState   = osOpening;
      boolNext = true;
      FRefCount= 0;
   }
   else if (FState == osOpened)
      result   = crSuccess;
   Unlock();

   // 判断是否继续
   if (boolNext)
   {
      // 执行打开
      boolNext = false;
      result   = DoOpen();

      // 更改状态
      Lock();
      if (FState != osOpening)
         boolNext = true;
      else if (result == crSuccess)
         FState   = osOpened;
      else
         FState   = osInactive;
      Unlock();

      // 判断是否需要关闭
      if (boolNext)
      {
         // 执行关闭
         if (result == crSuccess)
         {
            DoClose(true);
            result = crFailure;
         }

         // 更改状态(不需要加锁)
         FState = osInactive;
      }
   }

   // 返回结果
   return result;
}

// 关闭
void TRFConnObj::Close(bool ANeedWait)
{
   // 初始化
   bool boolNext  = false;
   bool boolWait  = false;

   // 更改状态
   Lock();
   if (FState == osOpened)
   {
      FState   = osClosing;
      boolNext = true;
   }
   else if (FState == osOpening)
   {
      FState   = osClosing;
      boolWait = true;
   }
   else if (FState == osClosing)
      boolWait = ANeedWait;
   Unlock();

   // 判断是否等待
   if (boolWait)
   {
      // 等待 Close 结束
      while (FState == osClosing)
         Sleep(15);
   }
   else if (boolNext)
   {
      // 执行关闭
      DoClose(true);

      // 更改状态(不需要加锁)
      FState = osInactive;
   }
}

// 并行操作的方法
long TRFConnObj::<method>(...)
{
   // 初始化
   long result = crStateInvalid;

   // 引用计数加 1
   if (IncRefCount())
   {
      // 操作
      // ??? ... ...

      // 引用计数减 1
      DecRefCount();
   }

   // 返回结果
   return result;
}


    可以把 Open 和 Close 方法理解为打开和关闭并行处理之门,只有 Open 之后才有效。
当调用 Close 方法时,若还有其它线程正在操作相关方法,则会等待操作完成后才能关闭,
若已调用 Close 方法且状态为 osClosing 且其它线程开始操作相关方法时,则会直接返回
状态无效,并拒之门外。


    对象状态和引用计数配合使用会提高事件处理的并发性,且不会在边界状态时导致异常
发生,同时还可以保证系统的并发性能。在服务器程序的开发中会常用到引用计数和状态,
若完全理解 Open 和 Close 中状态处理,则有助于灵活运用到并发性高的软件开发中。


<远程文件系统>提供完整源码,下载地址如下:
   

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值