并行处理之引用计数与状态的使用
在并行处理过程中多线程对同一对象进行操作,而且操作各自独立,但又需要依赖对象
本身的状态,如已打开或已登录等等。这时需要给状态进行引用计数,以保证操作的有效和
并发性。
为了便于描述, 以<远程文件系统>中的客户端连接对象类(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::(...)
{
// 初始化
long result = crStateInvalid;
// 引用计数加 1
if (IncRefCount())
{
// 操作
// ??? ... ...
// 引用计数减 1
DecRefCount();
}
// 返回结果
return result;
}
可以把 Open 和 Close 方法理解为打开和关闭并行处理之门,只有 Open 之后才有效。
当调用 Close 方法时,若还有其它线程正在操作相关方法,则会等待操作完成后才能关闭,
若已调用 Close 方法且状态为 osClosing 且其它线程开始操作相关方法时,则会直接返回
状态无效,并拒之门外。
对象状态和引用计数配合使用会提高事件处理的并发性,且不会在边界状态时导致异常
发生,同时还可以保证系统的并发性能。在服务器程序的开发中会常用到引用计数和状态,
若完全理解 Open 和 Close 中状态处理,则有助于灵活运用到并发性高的软件开发中。
<远程文件系统>提供完整源码,下载地址如下:
补充:软件开发 , C++ ,