青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

大龍的博客

常用鏈接

統計

最新評論

SEH的強大功能之二(轉)

上一篇文章講述了SEH的異常處理機制,也即try-except模型的使用規則。本篇文章繼續探討SEH另外一項很重要的機制,那就是“有效保證資源的清除”,其實這才是SEH設計上最為精華的一個東東,對于C程序而言,它貢獻簡直是太大了。

  SEH的這項機制被稱為結束處理(Termination Handling),它是通過try-finally語句來實現的,下面開始討論吧!

try-finally的作用


  對于try-finally的作用,還是先看看MSDN中怎么說的吧!摘略如下:

The try-finally statement is a Microsoft extension to the C and C++ languages that enables 32-bit target applications to guarantee execution of cleanup code when execution of a block of code is interrupted. Cleanup consists of such tasks as deallocating memory, closing files, and releasing file handles. The try-finally statement is especially useful for routines that have several places where a check is made for an error that could cause premature return from the routine.

  上面的這段話的內容翻譯如下:

  try-finally語句是Microsoft對C和C++語言的擴展,它能使32位的目標程序在異常出現時,有效保證一些資源能夠被及時清除,這些資源的清除任務可以包括例如內存的釋放,文件的關閉,文件句柄的釋放等等。try-finally語句特別適合這樣的情況下使用,例如一個例程(函數)中,有幾個地方需要檢測一個錯誤,并且在錯誤出現時,函數可能提前返回。

try-finally的語法規則

   上面描述try-finally機制的有關作用時,也許一時我們還難以全面理解,不過沒關系,這里還是先看一下try-finally的語法規則吧!其實它很簡單,示例代碼如下:

//seh-test.c
#include <windows.h>
#include <stdio.h>

void main()
{
puts("hello");
__try
{
puts("__try塊中");
}
// 注意,這里不是__except塊,而是__finally取代
__finally
{
puts("__finally塊中");
}

puts("world");
}

上面的程序運行結果如下:
hello
__try塊中
__finally塊中
world
Press any key to continue

  try-finally語句的語法與try-except很類似,稍有不同的是,__finally后面沒有一個表達式,這是因為try- finally語句的作用不是用于異常處理,所以它不需要一個表達式來判斷當前異常錯誤的種類。另外,與try-except語句類似,try- finally也可以是多層嵌套的,并且一個函數內可以有多個try-finally語句,不管它是嵌套的,或是平行的。當然,try-finally多層嵌套也可以是跨函數的。這里不一一列出示例,大家可以自己測試一番。
另外,對于上面示例程序的運行結果,是不是覺得有點意料之外呢?因為 __finally塊中的put(“__finally塊中”)語句也被執行了。是的,沒錯!這就是try-finally語句最具有魔幻能力的地方,即 “不管在何種情況下,在離開當前的作用域時,finally塊區域內的代碼都將會被執行到”。呵呵!這的確是很厲害吧!為了驗證這條規則,下面來看一個更典型示例,代碼如下:

#include <stdio.h>

void main()
{
puts("hello");
__try
{
puts("__try塊中");

// 注意,下面return語句直接讓函數返回了
return;
}
__finally
{
puts("__finally塊中");
}

puts("world");
}

上面的程序運行結果如下:
hello
__try塊中
__finally塊中
Press any key to continue

  上面的程序運行結果是不是有點意思。在__try塊區域中,有一條return語句讓函數直接返回了,所以后面的put(“world”)語句沒有被執行到,這是很容易被理解的。但是請注意,__finally塊區域中的代碼也將會被予以執行過了,這是不是進一步驗證了上面了那條規則,呵呵!阿愚深有感觸的想:“__finally的特性真的很像對象的析構函數”,朋友們覺得如何呢?

   另外,大家也許還特別關心的是,goto語句是不是有可能破壞上面這條規則呢?因為在C語言中,goto語句一般直接對應一條jmp跳轉指令,所以如果真的如此的話,那么goto語句很容易破壞上面這條規則。還是看一個具體的例子吧!

#include <stdio.h>

void main()
{
puts("hello");
__try
{
puts("__try塊中");

// 跳轉指令
goto RETURN;
}
__finally
{
puts("__finally塊中");
}

RETURN:
puts("world");
}

上面的程序運行結果如下:
hello
__try塊中
__finally塊中
world
Press any key to continue

  呵呵!即便上面的示例程序中,goto語句跳過了__finally塊,但是__finally塊區域中的代碼還是被予以執行了。當然,大家也許很關心這到底是為什么?為什么try-finally語句具有如此神奇的功能?這里不打算深入闡述,在后面闡述SEH實現的時候會詳細分析到。這里朋友們只牢記一點,“不管是順序的線性執行,還是return語句或goto語句無條件跳轉等情
況下,一旦執行流在離開當前的作用域時,finally塊區域內的代碼必將會被執行”

try-finally塊中的異常


  上面只列舉了return語句和goto語句的情況下,但是如果程序中出現異常的話,那么finally塊區域內的代碼還會被執行嗎?上面所講到的那條規則仍然正確嗎?還是看看示例,代碼如下:

#include <stdio.h>

void test()
{
puts("hello");
__try
{
int* p;
puts("__try塊中");

// 下面拋出一個異常
p = 0;
*p = 25;
}
__finally
{
// 這里會被執行嗎
puts("__finally塊中");
}

puts("world");
}

void main()
{
__try
{
test();
}
__except(1)
{
puts("__except塊中");
}
}

上面的程序運行結果如下:
hello
__try塊中
__finally塊中
__except塊中
Press any key to continue

  從上面示例程序的運行結果來看,它是和“不管在何種情況下,在離開當前的作用域時,finally塊區域內的代碼都將會被執行到”這條規則相一致的。

__leave關鍵字的作用

  其實,總結上面的__finally塊被執行的流程時,無外乎三種情況。第一種就是順序執行到__finally塊區域內的代碼,這種情況很簡單,容易理解;第二種就是goto語句或return語句引發的程序控制流離開當前__try塊作用域時,系統自動完成對__finally塊代碼的調用;第三種就是由于在__try塊中出現異常時,導致程序控制流離開當前__try塊作用域,這種情況下也是由系統自動完成對__finally塊的調用。無論是第 2種,還是第3種情況,毫無疑問,它們都會引起很大的系統開銷,編譯器在編譯此類程序代碼時,它會為這兩種情況準備很多的額外代碼。一般第2種情況,被稱為“局部展開(LocalUnwinding)”;第3種情況,被稱為“全局展開(GlobalUnwinding)”。在后面闡述SEH實現的時候會詳細分析到這一點。
第3種情況,也即由于出現異常而導致的“全局展開”,對于程序員而言,這也許是無法避免的,因為你在利用異常處理機制提高程序可靠健壯性的同時,不可避免的會引起性能上其它的一些開銷。呵呵!這世界其實也算瞞公平的,有得必有失。

  但是,對于第2種情況,程序員完全可以有效地避免它,避免“局部展開”引起的不必要的額外開銷。實際這也是與結構化程序設計思想相一致的,也即一個程序模塊應該只有一個入口和一個出口,程序模塊內盡量避免使用goto語句等。但是,話雖如此,有時為了提高程序的可讀性,程序員在編寫代碼時,有時可能不得不采用一些與結構化程序設計思想相悖的做法,例如,在一個函數中,可能有多處的return語句。針對這種情況,SEH提供了一種非常有效的折衷方案,那就是__leave關鍵字所起的作用,它既具有像goto語句和return語句那樣類似的作用(由于檢測到某個程序運行中的錯誤,需要馬上離開當前的 __try塊作用域),但是又避免了“局部展開” 的額外開銷。還是看個例子吧!代碼如下:

#include <stdio.h>

void test()
{
puts("hello");
__try
{
int* p;
puts("__try塊中");

// 直接跳出當前的__try作用域
__leave;
p = 0;
*p = 25;
}
__finally
{
// 這里會被執行嗎?當然
puts("__finally塊中");
}

puts("world");
}

void main()
{
__try
{
test();
}
__except(1)
{
puts("__except塊中");
}
}

上面的程序運行結果如下:
hello
__try塊中
__finally塊中
world
Press any key to continue

  這就是__leave關鍵字的作用,也許大家在編程時很少使用它。但是請注意,如果你的程序中,尤其在那些業務特別復雜的函數模塊中,既采用了SEH機制來保證程序的可靠性,同時代碼中又擁有大量的goto語句和return語句的話,那么你的源代碼編譯出來的二進制程序將是十分糟糕的,不僅十分龐大,而且效率也受很大影響。此時,建議不妨多用__leave關鍵字來提高程序的性能。

try-finally深入


  現在,相信我們已經對try-finally機制有了非常全面的了解,為了更進一步認識try-finally機制的好處(當然,主人公阿愚認為,那些寫過Windows平臺下設備驅動程序的朋友一定深刻認識到try-finally機制的重要性),這里給出一個具體的例子。還記得,在《第21集 Windows系列操作系統平臺中所提供的異常處理機制》中,所講述到的采用setjmp和longjmp異常處理機制實現的那個簡單例程嗎?現在如果有了try-finally機制,將能夠很容易地來避免內存資源的泄漏,而且還極大地提高了程序模塊的可讀性,減少程序員由于不小心造成的程序bug等隱患。采用SEH重新實現的代碼如下:

#include <stdio.h>
#include <stdlib.h>

void test1()
{
char* p1, *p2, *p3, *p4;

__try
{
p1 = malloc(10);
p2 = malloc(10);
p3 = malloc(10);
p4 = malloc(10);

// do other job
// 期間可能拋出異常
}
__finally
{
// 這里保證所有資源被及時釋放
if(p1) free(p1);
if(p2) free(p2);
if(p3) free(p3);
if(p4) free(p4);
}
}

void test()
{
char* p;

__try
{
p = malloc(10);

// do other job
// 期間可能拋出異常

test1();

// do other job
}
__finally
{
// 這里保證資源被釋放
if(p) free(p);
}
}

void main( void )
{
__try
{
char* p;

__try
{
p = malloc(10);

// do other job

// 期間可能拋出異常
test();

// do other job
}
__finally
{
// 這里保證資源被釋放
if(p) free(p);
}
}
__except(1)
{
printf("捕獲到一個異常\n");
}
}

  呵呵!上面的代碼與采用setjmp和longjmp機制實現的代碼相比,是不是更簡潔,更美觀。這就是try-finally語句的貢獻所在。

總結

   (1) “不管在何種情況下,在離開當前的作用域時,finally塊區域內的代碼都將會被執行到”,這是核心法則。

   (2) try-finally語句的作用相當于面向對象中的析構函數。

   (3) goto語句和return語句,在其它少數情況下,break語句以及continue語句等,它們都可能會導致程序的控制流非正常順序地離開 __try作用域,此時會發生SEH的“局部展開”。記住,“局部展開”會帶來較大的開銷,因此,程序員應該盡可能采用__leave關鍵字來減少一些不必要的額外開銷。

  通過這幾篇文章中對SEH異常處理機制的深入闡述,相信大家已經能夠非常熟悉使用SEH來進行編程了。下一篇文章把try-except和try-finally機制結合起來,進行一個全面而綜合的評述,繼續吧!

posted on 2008-01-25 19:29 大龍 閱讀(541) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲精品久久视频| 亚洲伊人色欲综合网| 欧美激情一区二区三区| 中文国产亚洲喷潮| 欧美精品系列| 在线视频国内自拍亚洲视频| 欧美在线视频在线播放完整版免费观看 | 狠狠v欧美v日韩v亚洲ⅴ| 小嫩嫩精品导航| 99精品视频一区| 欧美日韩亚洲不卡| 亚洲一区二区三区精品在线观看 | 国产精品大片免费观看| 亚洲视频视频在线| 夜夜嗨一区二区| 国产精品国产精品| 午夜精品久久久久久久久久久久| 一本在线高清不卡dvd| 国产精品啊v在线| 欧美亚洲免费高清在线观看| 亚洲香蕉成视频在线观看 | 久久av二区| 久久精品免费| 亚洲国产免费看| 亚洲人屁股眼子交8| 欧美日韩一区不卡| 欧美在线视频免费| 久久伊伊香蕉| 99亚洲伊人久久精品影院红桃| 日韩视频永久免费观看| 国产精品视频yy9099| 久久一区精品| 欧美黄色成人网| 亚洲女优在线| 久久婷婷av| 亚洲视频二区| 欧美一区二区视频在线| 91久久国产综合久久91精品网站| 亚洲人妖在线| 国产一区二区三区自拍| 91久久精品国产91性色tv| 欧美少妇一区| 久久综合伊人| 欧美色播在线播放| 久久综合色影院| 欧美日韩国产欧美日美国产精品| 性欧美video另类hd性玩具| 久久色中文字幕| 亚洲在线国产日韩欧美| 亚洲视频在线观看三级| 久久综合久久综合九色| 欧美理论在线| 欧美有码视频| 欧美激情视频一区二区三区免费 | 亚洲一区在线播放| 在线成人欧美| 亚洲小视频在线观看| 亚洲精品久久久久| 欧美一级视频| 亚洲一区欧美| 免费成人你懂的| 久久精品国产一区二区三区免费看| 欧美激情综合五月色丁香| 久久人人97超碰国产公开结果| 欧美视频在线免费| 亚洲激情图片小说视频| 经典三级久久| 香蕉久久夜色精品| 午夜精品视频在线观看一区二区| 欧美精选在线| 亚洲激情一区二区| 亚洲成色777777女色窝| 午夜视频在线观看一区二区| 中文精品视频| 欧美日韩国产影片| 亚洲国产精品成人久久综合一区| 狠色狠色综合久久| 久久国产精品色婷婷| 久久成人在线| 国产日韩精品视频一区| 亚洲一区在线直播| 欧美一区二区三区视频在线| 欧美色播在线播放| 一区二区成人精品 | 久久精品国产第一区二区三区最新章节| 亚洲一区二区三区精品视频| 欧美日韩综合网| 亚洲视频在线一区观看| 午夜一区在线| 国产日韩亚洲欧美综合| 欧美一区二区三区成人| 久久久久综合| 在线播放中文字幕一区| 久久青草欧美一区二区三区| 美女黄网久久| 亚洲欧洲在线看| 欧美久色视频| 中文有码久久| 午夜一区二区三区不卡视频| 国产精品一区二区在线观看不卡| 亚洲一区二区日本| 久久xxxx| 亚洲电影av| 欧美日韩1区| 亚洲视频免费观看| 欧美在线视频观看| 在线观看91久久久久久| 免播放器亚洲一区| 亚洲精品在线观看免费| 亚洲欧美日韩在线一区| 国产日韩欧美另类| 久久一本综合频道| 亚洲精品中文字幕女同| 午夜久久资源| 在线免费观看欧美| 欧美日韩国产综合一区二区| 欧美有码在线观看视频| 男男成人高潮片免费网站| 亚洲日本在线观看| 亚洲欧美日韩国产一区二区| 国模精品娜娜一二三区| 欧美成人一区二区在线| 亚洲视频在线看| 蜜桃av噜噜一区| 在线亚洲成人| 黄色成人av在线| 欧美日韩三级| 久久免费国产| 在线亚洲激情| 欧美成人蜜桃| 欧美一区二区三区免费看| 亚洲国产精品高清久久久| 国产精品久久久久一区二区| 久久久久久免费| 一区二区高清在线| 欧美国产日韩一区二区三区| 香蕉成人伊视频在线观看 | 欧美亚洲视频在线观看| 亚洲第一福利视频| 国产精品国产三级国产专区53 | 久久成人一区| 99在线|亚洲一区二区| 免费观看成人| 欧美在线观看你懂的| 夜夜精品视频| 亚洲第一免费播放区| 国产日韩av高清| 国产精品激情av在线播放| 免费成人黄色av| 久久超碰97人人做人人爱| 亚洲一级一区| 中文久久乱码一区二区| 亚洲国产精品成人一区二区| 久久亚洲捆绑美女| 久久国产精品毛片| 欧美亚洲三级| 午夜国产不卡在线观看视频| 一区二区日韩伦理片| 亚洲人成毛片在线播放女女| 在线观看日韩av| 狠久久av成人天堂| 国内成人精品一区| 国产精品视频九色porn| 欧美午夜不卡视频| 欧美日韩直播| 国产精品啊v在线| 欧美午夜无遮挡| 欧美三级电影精品| 欧美视频在线观看 亚洲欧| 欧美日韩国产首页在线观看| 欧美激情91| 欧美日韩国产成人高清视频| 欧美不卡在线| 欧美另类久久久品| 欧美日韩国产在线播放网站| 欧美日韩精品伦理作品在线免费观看| 欧美波霸影院| 欧美日韩色综合| 国产精品久久久久久久第一福利| 国产精品久久| 国产一区二区三区自拍| 在线欧美电影| 日韩午夜一区| 亚洲一区二区三区免费在线观看 | 亚洲免费不卡| 欧美大片免费观看在线观看网站推荐| 亚洲欧洲av一区二区| 亚洲成人在线视频播放| 久久免费偷拍视频| 免费成人黄色av| 欧美高清一区二区| 亚洲精品免费一区二区三区| 99精品欧美一区二区蜜桃免费| 99视频超级精品| 亚洲欧美日韩国产| 久久精品最新地址| 欧美极品在线观看| 国产精品三级久久久久久电影| 国产在线精品一区二区中文| 黄色在线成人|