quest permission to access protected data, and then use it.
WaitForSingleObject(g_hSem, INFINITE);
g_dwProtectedData = 5;
dwTemp = g_dwProtectedData;
// Return the new value.
return (dwTemp);
}
__finally {
// 3. Allow others to use protected data.
ReleaseSemaphore(g_hSem, 1, NULL);
}
// 4. Continue processing--this code will never execute in this version.
dwTemp = 9;
return (dwTemp);
}
例2 Funcenstein2函数代码
在函数Funcenstein2中,我们在try程序段里加入了一个return返回语句。该返回语句告诉编译器,你想离开函数Funcenstein2并返回dwTemp内的内容5给调用函数。然而,如果此返回语句被执行,本线程永远不会释放指示灯信号,其它线程也就永远不会得到该指示灯信号。你可以想象,在多线程程序中这是一个多么严重的
问题。
但是,使用了中断处理句柄避免了这种情况发生。当返回语句试图离开try程序段时,编译器保证了在finally程序段内的代码得到执行。所以,finally程序段内的代码保证会在try程序段中的返回语句前执行。在函数Funcenstein2中,将调用ReleaseSemaphore放在finally程序段内保证了指示灯信号会得到释放。
在finally程序段内的代码被执行后,函数Funcenstein2立即返回。这样,因为try程序段内的return返回语句,任何finally程序段后的代码都不会被执行。因而Funcenstein2返回值是5,而不是9。
必须指出的是,当遇到例2中这种过早返回语句时,编译器需要产生额外的代码以保证finally程序段内的代码的执行。此过程称作为局域展开。当然,这必然会降低整个程序的效率。所以,你应该尽量避免使用这类代码。在后面我们会讨论关键词__leave,它可以帮助我们避免编写出现局域展开一类的代码。
2.2.3、例3--Funcenstein3
现在让我们对Funcenstein2做进一步改动,看看会出现什么情况(见例3)。
DWORD Funcenstein3(void) {
DWORD dwTemp;
// 1. Do any processing here.
.
.
.
__try {
// 2. request permission to access protected data, and then use it.
WaitForSingleObject(g_hSem, INFINITE);
g_dwProtectedData = 5;
dwTemp = g_dwProtectedData;
// Try to jump over the finally block.
goto ReturnValue;
}
__finally {
// 3. Allow others to use protected data.
ReleaseSemaphore(g_hSem, 1, NULL);
}
dwTemp = 9;
// 4. Continue processing.
ReturnValue:
return (dwTemp);
}
例3 Funcenstein3函数代码
在函数Funcenstein3中,当遇到goto语句时编译器会产生额外的代码以保证finally程序段内的代码得到执行。但是,这一次finally程序段后ReturnValue标签后面的代码会被执行,因为try或finally程序段内没有返回语句。函数的返回值是5。同样,由于goto语句打断了从try程序段到finally程序段的自然流程,程序的效率会降低。
2.2.4、例4--Funcfurter1
现在让我们来看中断处理真正展现其功能的一个例子。(见例4)。
DWORD Funcfurter1(void) {
DWORD dwTemp;
// 1. Do any processing here.
.
.
.
__try {
// 2. request permission to access protected data, and then use it.
WaitForSingleObject(g_hSem, INFINITE);
dwTemp = Funcinator(g_dwProtectedData);
}
__finally {
// 3. Allow others to use protected data.
ReleaseSemaphore(g_hSem, 1, NULL);
}
// 4. Continue processing.
return (dwTemp);
}
例4 Funcfurter1函数代码
设想try程序段内调用的Funcinator函数具有某种缺陷而造成无效内存读写。在16位视窗应用程序中,这会导致一个已定义好的错误信息对话框出现。在用户关闭对话框的同时该应用程序也终止运行。在不具有try-finally的W