防止可重新進入:一個有趣的類和一個很有用的宏!

來源:互聯網
上載者:User

這幾天在研究Todolist源碼,看到一簡短的類,很很有意思,現把源碼列下,並附上簡短說明:

 

 

// macro to help prevent re-entrancy in functions<br />//定義一個宏AF_NOREENTRANT,防止函數中可重新進入</p><p>#define AF_NOREENTRANT /<br /> static BOOL bAFInHere = FALSE; /<br /> if (bAFInHere) /<br /> return; /<br />CAutoFlag af(bAFInHere, TRUE);</p><p>class CAutoFlag<br />{<br />public:<br /> CAutoFlag(BOOL& bFlag, BOOL bState); //bFlag為引用參數<br /> virtual ~CAutoFlag();</p><p>protected:<br /> BOOL& m_bFlag; //引用內部成員<br /> BOOL m_bInitialState;</p><p>};<br />  

 

      //////////////////////////////////////////////////////////////////////</p><p>// 構造時m_bFlag初始化為bFlag的引用,設定m_bFlag(bFlag)的值為bState,</p><p>//////////////////////////////////////////////////////////////////////</p><p>CAutoFlag::CAutoFlag(BOOL& bFlag, BOOL bState) : m_bFlag(bFlag)</p><p>{</p><p>m_bInitialState = bFlag;</p><p>m_bFlag = bState; //此時m_bFlag初始化為bFlag的引用</p><p>}</p><p>CAutoFlag::~CAutoFlag()</p><p>{</p><p>m_bFlag = m_bInitialState; //析構時bFlag恢複原值。</p><p>}</p><p>下面我們看一下函數及宏的具體應用:</p><p>void CToDoListWnd::OnTimerAutoSave()</p><p>{</p><p>AF_NOREENTRANT // 防止OnTimerAutoSave同時被多個地方調用。</p><p>// don't save if the user is editing a task label</p><p>if (!GetToDoCtrl().IsTreeLabelEditing())</p><p>SaveAll(FALSE, FALSE, FALSE, FALSE);</p><p>}</p><p>int CCheckComboBox::GetCurSel() const</p><p>{</p><p>CAutoFlag af(m_bDrawing, FALSE); //把m_bDrawing設為FALSE,函數執行完後自動回復原值。</p><p>return CComboBox::GetCurSel();</p><p>}</p><p>

 

 

註:

重入即表示重複進入,首先它意味著這個函數可以被中斷,其次意味著它除了使用自己棧上的變數以外不依賴於任何環境(包括static),這樣的函數就是purecode(純程式碼)可重新進入,可以允許有該函數的多個副本在運行,由於它們使用的是分離的棧,所以不會互相干擾。如果確實需要訪問全域變數(包括static),一定要注意實施互斥手段。可重新進入函數在並行運行環境中非常重要,但是一般要為訪問全域變數付出一些效能代價。

 

在多線程(或多進程)程式設計中,“重入”是指多個線程或進程“同時”訪問某個程式碼片段(通常指某一函數)。因此,“可重新進入”就是指這個程式碼片段支援這樣的操作而不會產生任何問題。無狀態的程式碼片段肯定是可重新進入的,比如求兩個數的平方的函數,但如果程式碼片段共用某些資源(比如共用變數),則要達到可重新進入,必須使用一些同步和或互斥機制。

 

在單任務的系統中同樣有函數重入的問題,因為c/c++函數支援中斷和回調,為此編譯器在函數調用時將傳回值的地址做為一個參數壓棧;這就意味這,在你的函數執行的任何時候中斷都有可能發生,所以你在寫代碼的時候要加以小心,尤其是在設計中斷服務程式的時候。如果你想支援重入,最好寫成純程式碼(與任何全域變數無關),不得已用到全域變數,要對臨界區加鎖;如果你不想重入就關中斷,並保證你的函數是唯一執行個體運行。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.