`
sealbird
  • 浏览: 570556 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

CLucene源码剖析(三) 实现跨平台的线程安全

阅读更多
首页 > 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
分享到:
评论

相关推荐

    C++搜索引擎Clucene源码

    C++搜索引擎Clucene源码

    C++搜索引擎 CLucene源码

    CLucene是Lucene的一个C++端口,Lucene是一个基于java的高性能的全文搜索引擎。CLucene因为使用C++编写,所以理论上要比lucene快。

    CLUCENE资料合集+代码源码

    这是我学CLUCENE时期整理出来的几个不错的资料,我觉得里面总有一款会适合你,而且你所需要知道的技术里面基本上都是涵盖的,所以可以当作教材或者参考手册使用。(里面有CLUCENE,可以用的)

    clucene源码

    大名鼎鼎的clucene,是lucene的c++ 版; CLucene README ============== ------------------------------------------------------ CLucene is a C++ port of Lucene. It is a high-performance, full-featured ...

    CLucene 最新源码

    09年最新源码,鼎力推荐,吐血推荐。非常好的东西,值得学习。

    clucene2.3.3.4源码 windows下vs2013工程

    clucene2.3.3.4源码 CMake制作的,windows下的vs2013工程,编译通过,学习全文检索、搜索引擎的好资料

    lucene3源码分析

    lucene3源码分析

    CLucene

    用C++改写的Lucene

    搜索引擎 CLucene 源代码

    CLucene 是C++版本的Lucene, .CLucene API文档地址:http://clucene.sourceforge.net/doc/html/index.html

    clucene中文处理

    对clucene的一些改进,能够处理中文字符

    Clucene库以及自己封装好的Clucene方法库

    Clucene库,以及自己封装好的Clucene方法库。该库提供了可直接调用的用于建立索引,查询索引的接口。输出结果返回的是一个满足条件的文件链表。

    clucenes _64位

    clucene-core-2.3.3.4版本,cmake基于vs2012 64位库编译的c++源码,内部bin目录有编译好动态库,内有完整的源码,也可以自己编译。

    Clucene使用示例

    Clucene使用示例 用c++写的搜索引擎使用实例,简单明了,是一个非常好的学习资料

    luceneDemo_pure1aa_DEMO_clucene_

    对clucene0.9.21版本在vc6下调试demo希望对你的开发有帮助

    clucene-core lucene c

    Lucene是apache组织的一个用java实现全文搜索引擎的开源项目。 其功能非常的强大,api也很简单。总得来说用Lucene来进行建立 和搜索和操作数据库是差不多的(有点像),Document可以看作是 数据库的一行记录,Field...

    CLucene结构文档

    CLucene类结构文档 内嵌源代码及各类关系图

    clucene_32位

    clucene-core-2.3.3.4版本,基于vs2012版,cmake出来的c++源码,内部的bin目录有编译好的动态库

    clucene-core-2.3.3.4

    网上下载的代码在生成vs2005工程的时候包错,改动了下cmake的文件。成功生成了vs2005的工程。

    开放源代码的全文检索引擎Lucene

    一、 Lucene源码实现分析的说明··· 9 二、 Lucene索引文件格式··· 10 三、 一些公用的基础类··· 12 四、 存储抽象··· 13 五、 关于cLucene项目··· 15 第四节 Lucene索引构建逻辑模块分析··· ...

    Clucene库以及自己封装的方法库(补充)——对应的头文件和.lib索引文件

    上次那个库对应的.h和.lib忘了共享了。在这里补上

Global site tag (gtag.js) - Google Analytics