首页 > CLucene, 程序人生 > CLucene源码剖析(三) 实现跨平台的线程安全
CLucene源码剖析(三) 实现跨平台的线程安全
2009年5月29日 小武哥 发表评论 阅读评论
在多线程编程中,程序的线程安全(thread-safe)是十分重要的,要做到这一点,一方面要在程序设计的过程中,尽可能设计多的单线程访问的数据结构,一方面就是合理的使用锁(Mutex)。在CLucene中,实现了如下跨平台的锁相关的宏:
(1) _LUCENE_SLEEP(x) 挂起当前线程 x微秒
(2) _LUCENE_THREADMUTEX 线程锁(mutex)
(3) _LUCENE_CURRTHREADID 获取当前线程的thread ID
(4) _LUCENE_THREADID_TYPE thread ID的类型定义
通过上面几个宏,就可以实现基本的线程安全的相关操作。下面对上述宏的具体实现进行一一详细说明:
1.在windows平台下:
(1) _LUCENE_SLEEP(x)由系统API Sleep()实现
1
#define _LUCENE_SLEEP(x) Sleep(x)
(2) _LUCENE_THREADMUTEX由CRITICAL_SECTION相关的内容实现
1
#define _LUCENE_THREADMUTEX CL_NS(util)::mutex_win32
(3) _LUCENE_CURRTHREADID由系统API GetCurrentThreadId()实现
1
#define _LUCEN colla="E_CURRTHREADID GetCurrentThreadId()
(4) _LUCENE_THREADID_TYPE类型为 DWORD类型
1
#define _LUCENE_THREADID_TYPE DWORD
2.在unix平台下:
(1) _LUCENE_SLEEP(x)由系统函数 usleep()实现
1
#define _LUCENE_SLEEP(x) usleep(x*1000)
(2) _LUCENE_THREADMUTEX由pthread_mutex_t相关的内容实现
1
#define _LUCENE_THREADMUTEX CL_NS(util)::mutex_pthread
(3) _LUCENE_CURRTHREADID由pthread中的pthread_self()的实现
1
#define _LUCENE_CURRTHREADID pthread_self()
(4) _LUCENE_THREADID_TYPE类型为pthread_t类型
1
#define _LUCENE_THREADID_TYPE pthread_t
从上面的讲解过程中,我们可以看出_LUCENE_THREADMUTEX的实现,还是有一层包装的,在windows下是mutex_win32,在unix下是mutex_pthread,所以要想深入理解,还需要更加深入一步。
下面是mutex_win32的实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class mutex_win32
{
private:
CRITICAL_SECTION mtx;
public:
mutex_win32(const mutex_win32& clone);
mutex_win32();
~mutex_win32();
void lock();
void unlock();
};
mutex_win32::mutex_win32(const mutex_win32& clone){
InitializeCriticalSection(&mtx);
}
mutex_win32::mutex_win32()
{
InitializeCriticalSection(&mtx);
}
mutex_win32::~mutex_win32()
{
DeleteCriticalSection(&mtx);
}
void mutex_win32::lock()
{
EnterCriticalSection(&mtx);
}
void mutex_win32::unlock()
{
LeaveCriticalSection(&mtx);
}
下面是mutex_pthread的实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
class mutex_pthread
{
private:
pthread_mutex_t mtx;
public:
mutex_pthread(const mutex_pthread& clone);
mutex_pthread();
~mutex_pthread();
void lock();
void unlock();
private:
#ifndef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
pthread_t lockOwner;
unsigned int lockCount;
#endif
};
#ifdef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
bool mutex_pthread_attr_initd=false;
pthread_mutexattr_t mutex_pthread_attr;
#endif
#ifdef _CL__CND_DEBUG
#define _CLPTHREAD_CHECK(c,m) CND_PRECONDITION(c==0,m)
#else
#define _CLPTHREAD_CHECK(c,m) c;
#endif
mutex_pthread::mutex_pthread(const mutex_pthread& clone){
#ifdef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
_CLPTHREAD_CHECK(pthread_mutex_init(&mtx, &mutex_pthread_attr), "mutex_pthread(clone) constructor failed")
#else
#if defined(__hpux) && defined(_DECTHREADS_)
_CLPTHREAD_CHECK(pthread_mutex_init(&mtx, pthread_mutexattr_default), "mutex_pthread(clone) constructor failed")
#else
_CLPTHREAD_CHECK(pthread_mutex_init(&mtx, 0), "mutex_pthread(clone) constructor failed")
#endif
lockCount=0;
lockOwner=0;
#endif
}
mutex_pthread::mutex_pthread()
{
#ifdef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
if ( mutex_pthread_attr_initd == false ){
pthread_mutexattr_init(&mutex_pthread_attr);
pthread_mutexattr_settype(&mutex_pthread_attr, PTHREAD_MUTEX_RECURSIVE);
mutex_pthread_attr_initd = true;
}
_CLPTHREAD_CHECK(pthread_mutex_init(&mtx, &mutex_pthread_attr), "mutex_pthread(clone) constructor failed")
#else
#if defined(__hpux) && defined(_DECTHREADS_)
_CLPTHREAD_CHECK(pthread_mutex_init(&mtx, pthread_mutexattr_default), "mutex_pthread(clone) constructor failed")
#else
_CLPTHREAD_CHECK(pthread_mutex_init(&mtx, 0), "mutex_pthread(clone) constructor failed")
#endif
lockCount=0;
lockOwner=0;
#endif
}
mutex_pthread::~mutex_pthread()
{
_CLPTHREAD_CHECK(pthread_mutex_destroy(&mtx), "~mutex_pthread destructor failed")
}
void mutex_pthread::lock()
{
#ifndef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
pthread_t currentThread = pthread_self();
if( pthread_equal( lockOwner, currentThread ) ) {
++lockCount;
} else {
_CLPTHREAD_CHECK(pthread_mutex_lock(&mtx), "mutex_pthread::lock")
lockOwner = currentThread;
lockCount = 1;
}
#else
_CLPTHREAD_CHECK(pthread_mutex_lock(&mtx), "mutex_pthread::lock")
#endif
}
void mutex_pthread::unlock()
{
#ifndef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
--lockCount;
if( lockCount == 0 )
{
lockOwner = 0;
_CLPTHREAD_CHECK(pthread_mutex_unlock(&mtx), "mutex_pthread::unlock")
}
#else
_CLPTHREAD_CHECK(pthread_mutex_unlock(&mtx), "mutex_pthread::unlock")
#endif
}
由上面的实现可以看出,mutex_win32直接就是对CRITICAL_SECTION相关的操作进行了封装,而mutex_pthread是对pthread_mutex_t相关操作的封装。其实在这里,我不知道作者为什么要采用这种宏的方式,我觉得完全可以能过封装一个通用的Thread类和Mutex类,这样用起来更为方便,而且要做扩展也比较容易。
http://www.wuzesheng.com/?p=120
分享到:
相关推荐
2. **跨平台**:作为C++库,CLucene可以编译并在多个操作系统上运行,包括Windows、Linux、Mac OS X等,这增加了它的灵活性和应用范围。 3. **API设计**:CLucene提供了一套易于使用的API,开发者可以方便地集成到...
本文将深入探讨C++实现的全文搜索引擎——Clucene,通过对源码的剖析,来理解其核心概念、设计思想以及实现机制。 Clucene,作为一款开源的、基于C++的全文搜索引擎库,它提供了类似Java Lucene的功能,允许开发者...
在"09年最新源码"中,我们可以学习到CLucene如何实现这些功能,以及它如何处理C++编程中的内存管理、多线程和I/O操作。源码是学习一个软件实现细节的最好途径,通过阅读和理解CLucene的源码,开发者可以深入掌握全文...
大名鼎鼎的clucene,是lucene的c++ 版; CLucene README ============== ------------------------------------------------------ CLucene is a C++ port of Lucene. It is a high-performance, full-featured ...
CMake是一个跨平台的自动化构建系统,它可以生成各种IDE的项目文件,包括VS2013的.sln解决方案文件。首先,你需要下载并安装CMake,然后配置源码路径和生成路径,选择Visual Studio 2013作为目标生成器,运行CMake...
CLucene是基于C++语言实现的一个全文搜索引擎库,它是对Java版Lucene的移植,旨在为C++开发者提供与Lucene类似的搜索功能。Lucene是一个广泛使用的开源信息检索库,由Apache软件基金会维护,它提供了丰富的文本分析...
2. **跨平台**:由于是用 C++ 编写的,CLucene 可以在多种操作系统上运行,包括 Windows、Linux、Mac OS 等。 3. **易于集成**:CLucene 提供了清晰的 API,使得它能方便地集成到 C++ 项目中,开发者可以快速构建...
三、Clucene源码导入 将Clucene的源码文件夹添加到vc6工程中,确保所有头文件和源文件能够被正确引用。注意,Clucene可能依赖一些外部库如zlib和bzip2,需要确保这些库也已正确配置。 四、构建DEMO项目 在vc6中...
《CLucene:C++实现的全文搜索引擎库》 CLucene是一个用C++编写的全文搜索引擎库,它提供了高效、可扩展的文本搜索功能。在本文中,我们将深入探讨CLucene的核心特性、编译环境以及如何利用它进行开发。 1. **...
4. **性能优化**:Clucene在设计时考虑了效率问题,采用了内存映射、多线程等技术,使得索引构建和查询操作都能在较短时间内完成。 接下来,我们关注一下"自己封装好的Clucene方法库"。这样的封装通常是为了方便...
这是我学CLUCENE时期整理出来的几个不错的资料,我觉得里面总有一款会适合你,而且你所需要知道的技术里面基本上都是涵盖的,所以可以当作教材或者参考手册使用。(里面有CLUCENE,可以用的)
**正文** Clucene是一款开源的全文搜索引擎库,它是...而压缩包中的"testengine"文件可能是用于测试Clucene中文处理功能的一个示例工程,通过运行和调试这个工程,可以更好地理解并掌握Clucene处理中文的实现细节。
CLucene是Lucene的C++实现,为那些偏好或需要使用C++进行开发的程序员提供了在C++环境中构建全文搜索引擎的可能。Lucene是一个高性能、全文本搜索库,由Java编写,广泛应用于各种搜索引擎和信息检索系统。CLucene则...
总的来说,处理Clucene-core-2.3.3.4在VS2005下的构建问题,既需要深入理解C++和全文检索技术,也需要熟悉软件构建工具和跨平台开发的技巧。通过这个过程,开发者可以提升自己的技能,更好地应对实际项目中的挑战。
### Lucene3源码分析知识点概述 #### 一、全文检索的基本原理 ##### 1. 总论 全文检索系统是一种高效的信息检索技术,能够帮助用户在海量文档中快速找到包含特定关键词的信息。Lucene是Java领域内最受欢迎的全文...
6. **跨平台兼容性**:CMake的一个主要优点是跨平台性,这意味着Clucene不仅可以用于Windows,还可以在Linux、Mac OS X等其他支持C++的平台上构建。 总结,这个资源提供了Clucene的一个版本,用户需要具备CMake和VS...
Clucene,这个名称是“C++ Lucene”的简称,是一款基于Java Lucene库的开源、跨平台的信息检索库,专门为C++开发者设计。标题中的"clucene-0.9.10.tar"表明我们讨论的是Clucene的一个特定版本——0.9.10,它以tar...
Clucene-core-0.9.21是一款基于C++实现的开源搜索引擎库,它提供了类似于Java Lucene的功能,使得开发者能够方便地在C++环境中构建全文检索应用。这个压缩包包含了Clucene的核心源代码,对于想要理解搜索引擎工作...
CMake是一个跨平台的自动化构建系统,用于管理项目的构建过程,使得项目可以在不同的操作系统和编译器上进行构建。 三、CMake配置与编译 在Windows环境下,通过CMake可以生成Visual Studio的解决方案文件(sln)。...