日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

windows终止处理程序( __try __finally) 简单解析

發布時間:2024/4/11 windows 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 windows终止处理程序( __try __finally) 简单解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文大部分來自《windows核心編程》。

例1

//二話不說,直接上代碼
int
Funcenstein2() {__try{return 3;}__finally{//在函數返回之前會處理__finally里的內容cout<<"finally executed"<<endl;}return 4;//此函數返回3而不是4 }

?

通過使用終止處理程序可以防止過早的執行return語句。當return語句試圖退出try塊的時候,編譯器會讓finally代碼在它。即編譯器保證finally代碼塊在出try塊的時候return之前執行。

者可以想知道,編譯器是如何保證此功能的呢?原來當編譯器檢查程序代碼時,會發現try代碼里有一個return語句。于是,編譯器就會生成一些代碼先將返回值(例子中的 3)保存在一個由它創建的一個臨時變量里,然后再執行finally語句塊。這個過程被稱之前為局部展開(LOCAL UNWIND)。更確切的說,當系統因try代碼提前退出finally時就會發生局部展開。一旦finally代碼塊執行完畢,編譯器所創建的臨時變量值就會返回給函數調用者。

?

由此可見,為了讓整個機制運行起來,編譯器必須生成一些額外的代碼,而系統也要很執行一些額外的工作。在不同的cpu結構上,讓終止處理工作起來的步驟也不同。需要注意的是,應該避免在try代碼中使用return語句,因為這是對程序性能有害的。__leave關鍵字,它可以幫助我們發現那些有局部展開開銷的代碼

?

?例2

int Funcenstein3() {//在try中使用goto語句時,就會產生局部展開以執行finally代碼塊。//這一次當finally執行完之后。因為try和finally中都沒有函數返回語句,//所以ReturnValue標簽后面的代碼也會執行。因此這函數返回4。//但是由于代碼破壞了try塊到finally的正常執行流程,可能有比較大的性能損失,其程序取決于cpu體系結構。int ret=0;__try{ret=5;goto ReturnValue;}__finally{cout<<"finally executed"<<endl;} ReturnValue:return 4; }

?

?例3

在這個例子中,終止處理將真正證明它的價值。首先看一下代碼

DWORD Funcfurter1() {DWORD dwTemp;//1. do any processing here __try{WaitForSingleObject(g_hSem,INFINITE);dwTemp=Funcinator(g_dwProtectedData);}__finally{ReleaseSemaphore(g_hSem,1,NULL);}return dwTemp; }

假設try代碼塊中Funcinator函數存在一個缺陷會導致程序訪問非法的內存。如果沒有SEH這種情況下最絡導致Windows錯誤報告(WER)彈出一個對話框:“Application has stopped working”。這個對話框在Windows上經常可以見到。一旦用戶取消這個對話框,進程就會終止。但信號量依然被占用并再也得不到釋放。其他進程中的純種就會因為無休止的等待這個信號量而得不到CPU時間片。如果把信號量放在finally之中,即使用try中調用的函數發生了內存訪問違規這樣的異常,這個信號量也可以被釋放。但是,請注意,從Windows Vista開始,須顯式地保護try/finally框架,以確保在異常拋出時,finally代碼會執行。

?

?例4

現在不防做一個實驗,判斷一下這個函數的返回值

DWORD FuncalDoodLeDoo() {DWORD dwTemp=0;while (dwTemp<10){__try{if(dwTemp==2)continue;if(dwTemp==3)break;}__finally{dwTemp++;}dwTemp++;}dwTemp+=10;return dwTemp; }

讓我們逐步分析這個函數執行的過程:一開始將dwTemp賦值為0,然后try塊中的代碼開始執行,但是兩個if語句都為false。于是程序正常進入到finally代碼塊,在這里給dwTemp的值上加1,而finally塊后面的代碼又將dwTemp加1。

?

下一次循環開時,dwTemp=2,第一個if為true,程序試如果沒有__finally程序會跳到while條件判斷處執行,但dwTemp值班不會改變,這將會是一個死循環。但是現在我們有終止處理程序,系統注意到continue語句將會導致提前跳出try塊,于是強制執行finally語句塊。 在finally語句塊中dwTemp被增加到3.這次finally之后的代碼塊沒有機會執行。因此finally執行完之后程序跳到循環頂部執行。

?

現在我們分析第三次迭代,這次第一個if判斷表達式的值為false,第二個表達式的值為true,系統再次偵測到程序流想要提前跳出try塊,于是調用finally代碼塊,這里的dwTemp增加到4.因為break語句的執行程序控制流從whhile循環后開始繼續。因而finally塊之后循環以內的代碼就不會被執行了。而循環之后的代碼將dwTemp的值設置為14。這是程序最終返回的結果。不用我指明,請教也不會寫出FuncalDoodleDoo這樣的代碼。此處只是為了演示終止處理程序是如何工作的。‘

?

絕大多數部情況下,try塊中的提前退出都會被終止處理程序所捕獲,但是在進程或線程提前終止的情況下,系統沒法保證finally代碼塊的執行。調用ExitThread或者ExitProcess可以馬上終止純種或進程,而不會引發finally執行。同樣如果當前純種或者進程因為另一個程序調用TerminateThread或TerminateProcess而不得不結束,finally代碼塊也不會被執行,有一些c運行期函數比如(abort),因為在其內部最絡調用的是ExitProcess,也會導致finally塊不能執行。我們沒法阻止別的線程殺死我們的線程或進程,但是可以在自己的代碼中盡量避免對ExitThread或ExitProces的草率調用。

?

例5

DWORD Funcenstein4() {DWORD dwTemp;//1. do any processing here __try{WaitForSingleObject(g_hSem,INFINITE);g_dwProcectedData=5;dwTemp=g_dwProcectedData;//return the new valuereturn dwTemp; }__finally{ReleaseSemaphore(g_hSem,1,NULL);return 103;}dwTemp = 9;return dwTemp; }

在上面的函數中,try中的代碼試圖用return 返回給調用者。正如我們前面提到的那樣,試圖在try塊中提前退出函數導致編程器生成一些額外代碼,將函數返回結果保存在一個臨時變量中,然后執行finally中又多了一個return,那么導致103被寫入到編譯器生成的臨時變量時。從而覆蓋了原先的值5。而返回103

?

出處:http://www.cnblogs.com/zhangdongsheng/ 作者:張東升 QQ:290387340

總結

以上是生活随笔為你收集整理的windows终止处理程序( __try __finally) 简单解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。