引用计数自动管理对象的生存周期
2009-12-24 16:09
169 查看
//
// 引用计数在长时间线程过程中的使用
// cheungmine
//
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <process.h>
// It should be used if the worker class will use CRT functions
static HANDLE CrtCreateThread(LPSECURITY_ATTRIBUTES lpsa,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE pfnThreadProc,
LPVOID pvParam,
DWORD dwCreationFlags,
LPDWORD pdwThreadId)
{
// _beginthreadex calls CreateThread which will set the last error value before it returns
return (HANDLE) _beginthreadex(lpsa,
dwStackSize,
(unsigned int (__stdcall *)(void *)) pfnThreadProc,
pvParam,
dwCreationFlags,
(unsigned int *) pdwThreadId);
}
class CUserdata
{
public:
CUserdata():m_data(100)
{
printf("CUserdata()/n");
}
~CUserdata()
{
printf("~CUserdata()/n");
}
int m_data;
};
template< typename _Type > class ThreadParamT
{
volatile ULONG m_cRef;
// 私有的析构方法保证由引用计数自动管理对象的生存期
~ThreadParamT()
{
printf("~ThreadParamT()::m_cRef=%d/n", m_cRef);
}
public:
ULONG AddRef()
{
return (ULONG) InterlockedIncrement((volatile LONG*)&m_cRef);
}
ULONG Release()
{
if (InterlockedDecrement((volatile LONG*)&m_cRef)==0)
{
delete this;
return 0;
}
return m_cRef;
}
ThreadParamT():
m_cRef(1)
{
printf("ThreadParamT()::m_cRef=%d/n", m_cRef);
}
_Type t;
};
// 线程过程: 长时间执行的 线程过程
// AddRef() 和 Release()必须在线程中成对调用
static DWORD WINAPI LongTimeThreadProc( LPVOID lpParam )
{
ThreadParamT<CUserdata> *pthrParam = (ThreadParamT<CUserdata> *) lpParam;
// 入口处立即增加引用计数
pthrParam->AddRef();
// 模拟执行一个长时间的任务
printf("LongTimeThreadProc::Do a long time job....../n");
SleepEx(10000, 0);
// 返回时必须减少引用计数
pthrParam->Release();
return 0;
}
int main()
{
// 创建线程过程参数, 这个参数传递给线程之后, 生存期就由引用计数控制
ThreadParamT<CUserdata> * thrParam = new ThreadParamT<CUserdata>();
DWORD dwThrId;
HANDLE hThread = CrtCreateThread(0, 0, LongTimeThreadProc, (LPVOID)thrParam, 0, &dwThrId);
// 下面的代码假设我们来不急等待线程执行结束
// 此时, thrParam 的生存期有引用计数管理是适当的
DWORD dwRet = WaitForSingleObject(hThread, 5000);
assert(dwRet==WAIT_TIMEOUT);
CloseHandle(hThread);
// 此时仍可访问线程数据, 注意是否使用关键区保护
printf("此时仍可访问线程数据: %d/n", thrParam->t.m_data);
// 此时释放引用计数, 如果线程未结束, 则数据并未释放
thrParam->Release();
SleepEx(6000, 0);
printf("thrParam 已经不可用, 此时不可访问线程数据: %d/n", thrParam->t.m_data);
return 0;
}
// 引用计数在长时间线程过程中的使用
// cheungmine
//
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <process.h>
// It should be used if the worker class will use CRT functions
static HANDLE CrtCreateThread(LPSECURITY_ATTRIBUTES lpsa,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE pfnThreadProc,
LPVOID pvParam,
DWORD dwCreationFlags,
LPDWORD pdwThreadId)
{
// _beginthreadex calls CreateThread which will set the last error value before it returns
return (HANDLE) _beginthreadex(lpsa,
dwStackSize,
(unsigned int (__stdcall *)(void *)) pfnThreadProc,
pvParam,
dwCreationFlags,
(unsigned int *) pdwThreadId);
}
class CUserdata
{
public:
CUserdata():m_data(100)
{
printf("CUserdata()/n");
}
~CUserdata()
{
printf("~CUserdata()/n");
}
int m_data;
};
template< typename _Type > class ThreadParamT
{
volatile ULONG m_cRef;
// 私有的析构方法保证由引用计数自动管理对象的生存期
~ThreadParamT()
{
printf("~ThreadParamT()::m_cRef=%d/n", m_cRef);
}
public:
ULONG AddRef()
{
return (ULONG) InterlockedIncrement((volatile LONG*)&m_cRef);
}
ULONG Release()
{
if (InterlockedDecrement((volatile LONG*)&m_cRef)==0)
{
delete this;
return 0;
}
return m_cRef;
}
ThreadParamT():
m_cRef(1)
{
printf("ThreadParamT()::m_cRef=%d/n", m_cRef);
}
_Type t;
};
// 线程过程: 长时间执行的 线程过程
// AddRef() 和 Release()必须在线程中成对调用
static DWORD WINAPI LongTimeThreadProc( LPVOID lpParam )
{
ThreadParamT<CUserdata> *pthrParam = (ThreadParamT<CUserdata> *) lpParam;
// 入口处立即增加引用计数
pthrParam->AddRef();
// 模拟执行一个长时间的任务
printf("LongTimeThreadProc::Do a long time job....../n");
SleepEx(10000, 0);
// 返回时必须减少引用计数
pthrParam->Release();
return 0;
}
int main()
{
// 创建线程过程参数, 这个参数传递给线程之后, 生存期就由引用计数控制
ThreadParamT<CUserdata> * thrParam = new ThreadParamT<CUserdata>();
DWORD dwThrId;
HANDLE hThread = CrtCreateThread(0, 0, LongTimeThreadProc, (LPVOID)thrParam, 0, &dwThrId);
// 下面的代码假设我们来不急等待线程执行结束
// 此时, thrParam 的生存期有引用计数管理是适当的
DWORD dwRet = WaitForSingleObject(hThread, 5000);
assert(dwRet==WAIT_TIMEOUT);
CloseHandle(hThread);
// 此时仍可访问线程数据, 注意是否使用关键区保护
printf("此时仍可访问线程数据: %d/n", thrParam->t.m_data);
// 此时释放引用计数, 如果线程未结束, 则数据并未释放
thrParam->Release();
SleepEx(6000, 0);
printf("thrParam 已经不可用, 此时不可访问线程数据: %d/n", thrParam->t.m_data);
return 0;
}
相关文章推荐
- 引用计数自动管理对象的生存周期
- netty的对象的生命周期管理——引用计数
- 编写一个智能指针类,自动记录SmartPointer<T*>对象的引用计数,一旦T类型对象的引用计数为零,就会释放对象
- 二段构造->REF引用计数管理->PoolManager自动释放池
- C++对象生命周期管理--通过引用计数指针对象来封装管理对象生命周期
- 为什么有时候C++运算符重载要返回引用,附对象生存周期
- 引用计数与对象生存期管理
- 今日学习 (使用.NET Remoting 建立分布式应用程序(二))(4月7日) ——对象生存周期管理
- .NET Remoting开发系列:(二) 对象生存周期管理
- OC学习篇之---数组对象的引用计数问题和自动释放池的概念
- C++的引用计数j控制智能指针——>Java的引用计数管理共享对象
- OC学习篇之---数组对象的引用计数问题和自动释放池的概念
- OC学习篇之---数组对象的引用计数问题和自动释放池的概念
- Java自动内存管理机制(三) 对象、引用
- OC学习篇之---数组对象的引用计数问题和自动释放池的概念
- 27、swift开发iOS——自动引用计数
- iOS 之ARC(自动引用计数)
- Swift-自动引用计数(Automatic Reference Counting)(十四)
- C++简单实现对象引用计数示例(转)
- 值类型变量所占用的内存空间位于线程堆栈中,而引用类型变量所引用的对象生存于托管堆中。