C++ 和C一样, 不能在函数内部嵌套地定义函数, 但C++允许函数内部声明和定义新的数据类型, 通过定义新数据类型的成员/静态函数, 可以间接地达到这一目的, 下面是通过这一技巧管理一个特定于一个函数的系统资源:
static int foo()
{
struct Local_CS_Resource {
Local_CS_Resource() {
printf("ctor: %s, %s, %d\n", __FILE__, __FUNCSIG__, __LINE__);
}
~Local_CS_Resource()
{
printf("dtor: %s, %s, %d\n", __FILE__, __FUNCSIG__, __LINE__);
}
} static cs_res;
return 0;
}
注意在函数foo内部, 声明了一个新的类型, 类型名在此处是必需的, 原因是我们要定义其ctor和dtor. 并需要在这两个函数中让C++的初始化RIIA和对象销毁机制发挥作用.
MSDN中给出的使用Crictial section的建议是: 在一个全局的地方声明, 定义和初始化, 在某个特定的函数内部成对使用
EnterCriticalSection
和
LeaveCriticalSection
ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.en/dllproc/base/using_critical_section_objects.htm
微软给出的例子是在main函数中:
void main() { ...
// Initialize the critical section one time only.
if (!InitializeCriticalSectionAndSpinCount(&CriticalSection, 0x80000400) ) return; ...
// Release resources used by the critical section object.
DeleteCriticalSection(&CriticalSection) }
|
而在下面的函数中使用
DWORD WINAPI ThreadProc( LPVOID lpParameter ) { ...
// Request ownership of the critical section.
EnterCriticalSection(&CriticalSection);
// Access the shared resource.
// Release ownership of the critical section.
LeaveCriticalSection(&CriticalSection);
... }
|
这种方法的问题在于封装和模块化的程度不够, 如果使用这一CriticalSection的函数跟main不在一个模块中, 就需要对全局变量有一个都可以访问得到的声明, 而且本来是做同一件事情, 却因为这种机制本身的限制被人为地分散地多处进行, 上面的办法就可以避免这一问题:
静态对象的初始化在main或DllMain+Attach之前进行, 其销毁则在main或DllMain+Detach之后. 所以对critical section的所有操作就被封装在使用它的函数内部了.
阅读(555) | 评论(0) | 转发(0) |