`

LibXML多线程环境中的使用

    博客分类:
  • C++
阅读更多

LibXML在多线程环境中使用时,需要注意xmlInitParser与xmlCleanUpParser两个函数的使用。

对于xmlInitParser与xmlCleanUpParser都需要在主线程中调用,不能在子线程中调用。

 

特别是xmlCleanUpParser,我在对LibXML库进行封装时,将该函数放到了析构函数中,然后在子线程的栈中创建了一个C++类对象,从而导致莫名的运行时错误。(由于栈对象销毁调用析构函数,调用了xmlCleanUpParser函数,因此在第二次进入线程循环时,调用LibXML库函数,会触发运行时错误。)

 

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

以下为一个总结较好的使用心得,转自:http://blog.csdn.net/Gavin_Han/archive/2007/09/21/1795032.aspx

 

使用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;

 }  

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

分享到:
评论

相关推荐

    移植到ARM的libxml

    如果libxml将在多线程环境中使用,需要确保其线程安全。ARM架构可能有特定的线程管理机制,需要确认libxml的多线程实现与之兼容。 10. **嵌入式系统考虑** 对于嵌入式ARM设备,空间和资源限制可能更为严格。可能...

    linux下c语言多线程网页爬虫源代码

    在多线程环境中,尤其要注意内存分配和释放的同步,防止内存泄漏。 10. **日志和调试**:为了追踪程序运行情况和调试,爬虫应包含日志记录功能。GDB是Linux下的一个强大的调试工具,可以帮助定位和修复问题。 综上...

    GNU libxml2 bcb开发包

    由于libxml2-2.7.3版本可能涉及到多线程操作,因此在分发应用程序时,需要包含Borland的多线程动态库,如`libmt.lib`,以确保在多线程环境下正确运行。这要求开发者在配置项目时,确保选择正确的链接器选项,以链接...

    多线程C++爬虫程序

    本项目涉及的主题是“多线程C++爬虫程序”,这将涵盖多线程编程和网络爬虫的基本概念,以及如何在C++语言环境中实现这两个技术的结合。 首先,我们来理解“爬虫”这一概念。网络爬虫(Web Crawler)是自动遍历...

    c++多线程抓取网页代码

    在多线程环境下,我们需要确保libcurl的线程安全。为此,我们需调用 `curl_global_init` 之前调用 `curl_thread_init`,并在程序结束时调用 `curl_thread_cleanup`。 下载的网页内容通常以HTML形式返回,我们可以...

    c++_libxml解析xml.doc

    1. 在 VC 环境中设置 lib 和 include 路径,并在 link 设置中添加 libxml2.lib 和 iconv.lib。 2. 使用编译器选项告诉编译器 cl.exe 头文件的位置,并用链接器选项告诉链接器 link.exe 库文件的位置,同时在 Windows...

    Libxml2-windows版本

    例如,通过调整解析选项,或者利用多线程并行解析,可以提升处理大量XML数据的效率。 总结来说,"Libxml2-windows版本"是一个包含所有必需组件的包,使得在Windows平台上开发和运行使用Libxml2的XML处理应用变得...

    个人总结C语言下xml使用全集-libxml.docx

    在Makefile中,`CPP_FLAGS`定义了编译选项,包括使用多线程Debug库、生成完整调试信息等;`INCLUDE_FLAGS`指定了头文件路径;`LIB_PATH_FLAGS`则设置了库文件路径。通过nmake命令,你可以轻松地编译和链接源代码。 ...

    简易C++爬虫框架,基于多线程、多任务,快速实现网络数据爬取

    任务调度在多线程环境中尤为重要,它决定了哪些任务应该优先执行,以及如何分配资源。在爬虫框架中,可能有一个调度器负责分配任务给各个线程,比如维护一个待爬取URL的队列,每当线程完成一个任务后,就从队列中...

    C语言多线程爬虫源代码

    【标题】"C语言多线程爬虫源代码"揭示了这个项目的核心是使用C语言编写的一款能够在Linux操作系统环境下运行的网络爬虫程序。爬虫是互联网数据抓取的重要工具,它能自动化地遍历网页并提取所需信息。C语言因其高效、...

    Android编译环境搭建.pdf

    - NDK包含了构建高性能、多线程应用所需的C和C++库和工具。在搭建编译环境时,需要下载并配置NDK环境。 - SDK则包含了各种Android平台和设备的API,用于Android应用开发。 5. 环境验证与问题解决: - 在完成上述...

    multi_threads_xml

    在多线程环境中使用`libxml2`时,需要注意其线程安全特性。虽然`libxml2`本身具有一定的线程安全性,但在某些情况下,比如解析和修改同一文档,还是需要开发者进行适当的同步控制。 为了优化多线程处理XML,还可以...

    分布式网络爬虫设计毕业设计.pdf

    在多线程环境下,需要使用互斥锁(如pthread_mutex_t)确保线程安全。 7. **消息队列设计**:Nanomsg库提供跨线程、跨进程、跨机器的通信能力。在本设计中,使用NN_PIPELINE模式,保证数据按顺序单向流动,从一个...

    lxml学习手册

    - **多线程访问**: 是否可以在多线程环境中并发访问lxml API。 - **性能提升**: 多线程是否能显著提升程序性能。 - **线程关闭**: 单线程程序是否会在关闭线程后性能更好。 - **XSLT重用**: 为何不能在多线程中重用...

    在linux下编译Qt源码,测试环境乌班图

    由于编译过程可能需要较长时间,可以使用多线程加速: ```bash make -j4 ``` 最后,使用`sudo make install`将编译好的Qt库安装到系统中,使其可供全局使用。记得在环境变量中添加Qt的可执行文件路径,例如: ```...

    多进程互斥读写XML文件

    - 在多进程环境中,一个进程可能正在读取文件,而另一个进程可能尝试写入,如果不加以控制,可能会导致数据交错,破坏文件结构。 2. **多进程与多线程** - **多进程**:操作系统中同时运行的多个独立执行单元,每...

    UNIX操作系统教程 张红光

    Window的特征292 14.1.2X-Window的工作方式293 14.1.3X-Window的组成部件294 14.1.4X-Window编程环境介绍295 14.2数据检索加工工具awk296 14.2.1awk基本描述296 14.2.2awk中的记录和字段297 14.2.3awk中使用的模式...

    C++ 高性能爬虫代码,带UI

    在C++中实现高性能的网络爬虫是一项技术挑战,需要对多线程、异步IO、数据解析以及UI交互有深入理解。 首先,C++是一种静态类型的、编译式的、通用的、大小写敏感的、不仅支持过程化编程,也支持面向对象编程的程序...

    mp4v2库.rar

    - **多线程与并发**:如果应用需要在多个线程中同时操作MP4文件,需要了解库对多线程支持的程度,以及如何正确使用同步原语。 - **性能优化**:掌握如何高效地使用MP4v2库,以减少不必要的I/O操作和内存消耗。 综上...

    xmlrpc-c源码包

    5. **线程安全**:xmlrpc-c库设计为线程安全的,可以在多线程环境中使用。 6. **示例和文档**:源码包通常会包含示例代码和文档,帮助开发者快速理解和使用库。 对于xmlrpc-c-1.43.08这个特定版本,我们可以期待它...

Global site tag (gtag.js) - Google Analytics