xmlInitParser 和 xmlCleanupParser 使用詳解

來源:互聯網
上載者:User

使用libxml2庫的朋友,可能會對它提供的初始化介面(xmlInitParser )和清除資源介面(xmlCleanupParser )感到困惑.因為在它首頁中提供的例子裡面,各處使用的情況差別很大. 我花了些時間把這兩個介面使用方法整理如下:

1. 在單線程(single-threaded)環境中

   xmlInitParser 可以被調用一次,或者被調用多次(多於一次),甚至可以不被調用.

   對於第一種情況,很容易理解,因為介面作用是初始化,而且應該在程式的入口處調用. 這也是推薦的使用方法.

   對於第二種情況,看其介面的實現代碼就很容易理解,第二次以後的調用只是判斷完標誌位後簡單地返回.

   --------------------------------------------------------------------------------

   void xmlInitParser(void) {
    if (xmlParserInitialized != 0)
        return;

   //do initialization for xml library
   …

    xmlParserInitialized = 1;
   }

   --------------------------------------------------------------------------------

   對於第三種情況,在作者在mailing list的回答中可找到答案,而且這一點我也已經簡單地通過例子驗證過.而且在libmxl2內建的很多sample中,都是屬於這樣的情況.

   --------------------------------------------------------------------------------

   http://mail.gnome.org/archives/xml/2003-May/msg00027.html

   Q:  1. If I *don't* use libxml2's thread-support do I have to call xmlInitParser() only once per application or once per parsing?

   A:  You don't even need to call it. It's done automatically, it's just better to do it explicitly in a thread environment.

   --------------------------------------------------------------------------------

   類似於xmlInitParser(), xmlCleanupParser()也可以被調用一次,或者被調用多次(多於一次),甚至可以不被調用.

    對於第一種情況,很容易理解,因為介面作用是清除資源的, 而且應該在程式的出口處調用. 這也是推薦的使用方法.

   對於第二種情況,看其介面的實現代碼就很容易理解,第二次以後的調用只是判斷完標誌位後簡單地返回.

   --------------------------------------------------------------------------------

  void xmlCleanupParser(void) {

    if (!xmlParserInitialized)        return;     // do cleanup for xml library   …     xmlParserInitialized = 0;

   }

   --------------------------------------------------------------------------------

   對於第三種情況,這樣的使用方法不會對程式造成任何的破壞,但是在xmlInitParser()中分配的部分記憶體將一直被佔用,直至整個程式退出.所以這是一種不會產生影響但也不推薦的使用方法.

2. 在多線程(multi-threaded)環境中

   在多線程環境下,使用它們要比單線程環境下面需要注意更多的問題.

   使用xmlInitParser()必須遵循一下兩個原則:

   (1) xmlInitParser()不能線上程中被調用,因為xmlInitParser()不是原子操作,可能會引起線程競爭,導致程式意外.

   (2) xmlInitParser()應該在主線程中被調用,在開始任何線程之前,在程式的入口處.

   從原則上如果整個程式中不調用xmlInitParser()在某些情況是可以的,因為上一節提到,調用任何其他libxml2 API時會檢驗是否已經初始化,如果沒有,將自動進行初始化. 但是如果在整個開始線程之前的進程中都沒有調用到libxml2 的任何API,而是線上程開始調用libxml2的API,就會出現初始化時線程競爭的糟糕事情.所以這是非常不推薦的做法.

   當然,在進程(線程開始前)多次調用xmlInitParser()不會產生問題,因為第二次以後的調用只是簡單地檢查標誌位接下來返回.

   使用xmlCleanupParser()必須遵循一下兩個原則:

   (1) xmlCleanupParser()不能線上程中被調用,因為先結束的進程會把共用記憶體清除,接下來尚未結束的的線程就無法正確訪問.

   (2) xmlCleanupParser()應該在主線程中被調用,在不再使用libxml2庫時,一般在程式的出口處.

   這裡需要注意一個問題,如果你無法確定其他使用者是否還在使用libxml2庫,那麼就不要調用xmlCleanupParser(),因為這樣最差的情況是浪費了一塊記憶體,直至在程式結束時才能被收回,比起程式崩潰,這樣的代價還是值得的.在mailing list中,作者也提到這樣的方案.

   同樣,在進程(所有進程結束之後)多次調用xmlCleanupParser()不會對程式產生任何影響,第二次以後的調用僅是檢查標誌位和簡單第返回.

   在多線程環境下,推薦的使用方法是:

   ------------------------------------------------------------------------------

  int main ( int argc, char **argv )  {   //do library initialization at the beginning of the program   xmlInitParser();     //do other program initialization    …     //start thread    for (i = 0; i < num_threads; i++) {      ret = pthread_create           …   }    //do other program initialization   …     //do library cleanup when the program ends up    xmlCleanupParser(();    return 0;

 }  

 ------------------------------------------------------------------------------ 

以上是我總結的在單線程和多線程環境下使用xmlInitParser()和xmlCleanupParser()時需要注意的幾點,歡迎大家補充!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.