xmlInitParser 和 xmlCleanupParser 使用详解

原创 2007年09月21日 17:22:00

使用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()时需要注意的几点,欢迎大家补充!

 

2007/09/21 晚

 

xmlInitParser和xmlCleanupParser使用详解

  xmlInitParser 和 xmlCleanupParser 使用详解 收藏使用libxml2库的朋友,可能会对它提供的初始化接口(xmlInitParser )和清除资源接口(xmlClea...
  • needle2
  • needle2
  • 2010年09月04日 15:15
  • 3747

xmlInitParser和xmlCleanupParser使用详解 http://blog.csdn.net/hdutigerkin/article/details/7548596

xmlInitParser和xmlCleanupParser使用详解 2012-05-09 09:34 347人阅读 评论(0) 收藏 举报 initialization多线程libr...
  • wangyin159
  • wangyin159
  • 2015年08月31日 08:20
  • 393

libxml使用实例

libxml21 声明指针:                              文档指针(xmlDocPtr),结点指针(xmlNodePtr);2 得到文档doc:         xmlR...
  • needle2
  • needle2
  • 2010年09月04日 15:14
  • 3639

使用 ACEXML 来解析一个 xml 文件

本段代码通过ACEXML来解析一个XML文件,并且生成了一棵树,树的存储采用孩子兄弟存储的方法。 在连接生成可执行文件的时候,连接一下文件: ACEd.lib ACEXMLd.lib ACEXML...
  • u010856711
  • u010856711
  • 2013年06月15日 11:21
  • 1671

xmlInitParser 和 xmlCleanupParser 使用详解

使用libxml2库的朋友,可能会对它提供的初始化接口(xmlInitParser )和清除资源接口(xmlCleanupParser )感到困惑.因为在它主页中提供的例子里面,各处使用的情况差别很大...
  • Gavin_Han
  • Gavin_Han
  • 2007年09月21日 17:22
  • 6582

ios 自带xml 解析,TBXMLParser解析

今天看了下苹果xml 解析,写了个小demo 心想还是 在博客上写点东西吧,毕竟很久很久都没有上来了 先上个效果图把 接下来 看下 工程目录图吧 本demo 分两种解析模式,一是苹果自带的...
  • chonbj
  • chonbj
  • 2014年05月16日 14:17
  • 13732

xmlInitParser和xmlCleanupParser 多线程操作

使用libxml2库的朋友,可能会对它提供的初始化接口(xmlInitParser )和清除资源接口(xmlCleanupParser )感到困惑.因为在它主页中提供的例子里面,各处使用的情况差别很大...
  • hanchaoman
  • hanchaoman
  • 2012年04月20日 18:25
  • 1886

libxml编程--内存泄露

最近在项目中使用到了libxml函数库,使用过程中用valgrind进行检测的时候发现了一些内存泄露。   主要是两个问题,现整理如下。   1.xmlGetProp函数        调用这个函...
  • allen_ydc
  • allen_ydc
  • 2015年10月11日 11:36
  • 530

vs2010未能正确加载XX包的解决方法

可以在cmd里切换到安装目录下的Common7/IDE,然后运行devenv /ResetSettings 比如我的地址是 D:\Program Files\Microsoft Visual ...
  • qq0824
  • qq0824
  • 2016年08月31日 17:10
  • 1305

解析xml初始化数据库

项目的研发或者上线阶段,为了方便,可能需要初始化数据库:包括用户,权限,或者一些其他的基础数据。我这里采用的是解析Xml文件初始化数据库。   (1)Xml文件的格式如下:     (2)配...
  • u013628152
  • u013628152
  • 2015年01月04日 14:37
  • 1145
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:xmlInitParser 和 xmlCleanupParser 使用详解
举报原因:
原因补充:

(最多只允许输入30个字)