● 實現了線程間互斥鎖
● 實現優(yōu)化了單線程環(huán)境中的空鎖和空級別鎖
● 支持編譯時或運行時選擇鎖
● 支持對象和類級別的鎖粒度
● 支持錯誤或異常處理
框架結構
由鎖抽象、鎖適配器、鎖守衛(wèi)、線程互斥鎖和鎖級別5個基本組件構成,對應類的關系如下圖。

鎖抽象
提供鎖語義的抽象,一般有5種操作:創(chuàng)建或初始化、阻塞加鎖、非阻塞加鎖、解鎖和銷毀,實現為lock_base類。
1
class lock_base
2
{
3
public:
4
lock_base(){}
5
virtual ~lock_base(){}
6
7
virtual int lock() = 0;
8
virtual int trylock() = 0;
9
virtual int unlock() = 0;
10
};

2

3

4

5

6

7

8

9

10

鎖適配器
支持運行時動態(tài)綁定某個具體鎖,實現為lock_adapter類模板,繼承l(wèi)ock_base。
1 template<class T>
2 class lock_adapter : public lock_base
3
{
4
public:
5
lock_adapter(T &lock)
6
:lock_(&lock)
7
,del_(false)
8
{}
9
10
lock_adapter()
11
:del_(true)
12
{ lock_ = new T(); }
13
14
~lock_adapter()
15
{ if(del_) delete lock_; }
16
17
virtual int lock()
18
{ return lock_->lock(); }
19
20
virtual int trylock()
21
{ return lock_->trylock(); }
22
23
virtual int unlock()
24
{ return lock->unlock(); }
25
26
private:
27
T *lock_;
28
bool del_;
29
};
2 class lock_adapter : public lock_base
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

線程互斥鎖
一種支持線程間同步的具體鎖,支持windows和linux平臺,實現為thread_mutex類。
1
thread_mutex::thread_mutex()
2
{
3
#ifdef _WIN32
4
//because use SEH
to handle API exception, so instead of using one free function to initialize the critical section
5
init_critical_section(&m_);
6
#else
7
int ret;
8
if(ret=pthread_mutex_init(&m_,NULL))
9
throw lock_error("pthread_mutex_init",ret);
10
#endif
11
}
12
13
thread_mutex::~thread_mutex()
14
{
15
#ifdef _WIN32
16
DeleteCriticalSection(&m_);
17
#else
18
pthread_mutex_destroy(&m_);
19
#endif
20
}
21
22
int thread_mutex::lock()
23
{
24
#ifdef _WIN32
25
EnterCriticalSection(&m_);
26
return 0;
27
#else
28
int ret;
29
if(ret=pthread_mutex_lock(&m_)){
30
errno = ret;
31
return -1;
32
}
33
return 0;
34
#endif
35
}
36
37
int thread_mutex::trylock()
38
{
39
#ifdef _WIN32
40
#if (defined _WIN32_WINNT) && _WIN32_WINNT >= 0x0400
41
if(!TryEnterCriticalSection(&m_)){
42
errno = EBUSY;
43
return -1;
44
}
45
return 0;
46
#endif
47
errno = ENOSYS;
48
return -1;
49
#else
50
int ret;
51
if(ret=pthread_mutex_trylock(&m_)){
52
errno = ret;
53
return -1;
54
}
55
return 0;
56
#endif
57
}
58
59
int thread_mutex::unlock()
60
{
61
#ifdef _WIN32
62
LeaveCriticalSection(&m_);
63
return 0;
64
#else
65
int ret;
66
if(ret = pthread_mutex_unlock(&m_)){
67
errno = ret;
68
return -1;
69
}
70
return 0;
71
#endif
72
}

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

1
class null_mutex
2
{
3
public:
4
int lock() { return 0;}
5
int trylock() { return 0;}
6
int unlock() { return 0; }
7
};

2

3

4

5

6

7

鎖守衛(wèi)
用于自動獲取和釋放鎖,保證當異常發(fā)生時能自動解鎖,實現為lock_guard類模板,T表示鎖類型,只要這個類型提供lock、trylock和unlock三種語義。
1
template<class T>
2 class lock_guard : noncopyable
3
{
4
public:
5
explicit lock_guard(T &lock, bool block=true)
6
: lock_(&lock)
7
{
8
owner_ = (block ? lock_->lock() : lock_->trylock());
9
}
10
11
~lock_guard()
12
{
13
if(0==owner_) lock_->unlock();
14
}
15
16
int locked() const
17
{ return owner_; }
18
19
private:
20
T *lock_;
21
int owner_;
22
};

2 class lock_guard : noncopyable
3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

1
template<>
2
class lock_guard<null_mutex>
3
{
4
public:
5
explicit lock_guard(null_mutex&){}
6
~lock_guard() {}
7
};

2

3

4

5

6

7

鎖級別
提供類級別和對象級別2種鎖粒度:類級別是指所有對象共享同一個鎖,實現為class_level_lock類模板;對象級別是指每個對象持有自己的鎖, 實現為object_level_lock類模板。
1
template<class T>
2
class level_lock_base : noncopyable
3
{
4
public:
5
typedef lock_guard<const T> lock_guard_type;
6
7
int lock() const
8
{ return static_cast<const T*>(this)->lock_.lock(); }
9
10
int trylock() const
11
{ return static_cast<const T*>(this)->lock_.trylock();}
12
13
int unlock() const
14
{ return static_cast<const T*>(this)->lock_.unlock(); }
15
16
protected:
17
~level_lock_base(){}
18
};
19
20 template<class T,class L>
21 class class_level_lock : public level_lock_base<class_level_lock<T,L> >
22
{
23
template<class U>
24
friend class level_lock_base;
25
26
protected:
27
~class_level_lock(){}
28
29
private:
30
static L lock_;
31
};
32
33 template<class T,class L>
34 L class_level_lock<T,L>::lock_;
35
36 template<class T,class L>
37 class object_level_lock : public level_lock_base<object_level_lock<T,L> >
38
{
39
template<class U>
40
friend class level_lock_base;
41
42
protected:
43
~object_level_lock(){}
44
45
private:
46
mutable L lock_;
47
};

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20 template<class T,class L>
21 class class_level_lock : public level_lock_base<class_level_lock<T,L> >
22

23

24

25

26

27

28

29

30

31

32

33 template<class T,class L>
34 L class_level_lock<T,L>::lock_;
35

36 template<class T,class L>
37 class object_level_lock : public level_lock_base<object_level_lock<T,L> >
38

39

40

41

42

43

44

45

46

47

1 template<class T,class L>
2 class null_level_lock : public level_lock_base<null_level_lock<T,L> >
3
{
4
protected:
5
~null_level_lock(){}
6
};
7
8 template<class T,class L>
9 class lock_guard<const null_level_lock<T,L> >
10
{
11
public:
12
explicit lock_guard(const null_level_lock<T,L>&){}
13
~lock_guard(){}
14
};
2 class null_level_lock : public level_lock_base<null_level_lock<T,L> >
3

4

5

6

7

8 template<class T,class L>
9 class lock_guard<const null_level_lock<T,L> >
10

11

12

13

14

應用示例
編譯時選擇鎖類型與級別
stl_sequence是以stl中的vector、list和deque三種序列容器為基礎進行共性抽象的包裝容器,為了使它靈活支持各種鎖與級別,就需要將鎖和級別定義為模板參數,并提供一個默認的類型。
1
template<typename T,
2
class L = null_mutex, //lock type
3
template<class T,class L> class E = null_level_lock, //lock level
4
template<class T,class U> class C = std::vector,
5
template <class T> class U = std::allocator
6
>
7
class stl_sequence : private E<stl_sequence<T,L,E,C,U>,L>
8
{
9
typedef U<T> Allocator;
10
typedef C<T,Allocator> cont_type;
11
typedef stl_sequence<T,L,E,C,U> self_type;
12
typedef E<self_type,L> base_type;
13
typedef typename base_type::lock_guard_type lock_guard_type;
14
15
public:
16

17
void add(const T &t,bool append = true)
18
{
19
lock_guard_type guard(*this);
20
//do add thing
21
}
22
23
void insert(size_t idx,const T &t)
24
{
25
lock_guard_type guard(*this);
26
//do insert thing
27
}
28
29
void erase(size_t idx)
30
{
31
lock_guard_type guard(*this);
32
//do erase thing
33
}
34
35
T* get(size_t idx)
36
{
37
lock_guard_type guard(*this);
38
//do get thing
39
}
40

41
};

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

● 使用空級別鎖:seq1和seq2都沒有鎖,即使seq2使用了thread_mutex。
1
stl_sequence<int> seq1;
2
stl_sequence<int,thread_mutex> seq2;

2

1
stl_sequence<int,thread_mutex,object_level_lock> seq3, seq4;

1
stl_sequence<int,thread_mutex,class_level_lock> seq5, seq6;

1
stl_sequence<int,null_mutex> seq7;
2
stl_sequence<int,null_mutex,class_level_lock> seq8;
3
stl_sequence<int,null_mutex,object_level_lock> seq9;

2

3

運行時綁定具體鎖
1 lock_base *lb;
2 if(argc>1 && 0==strcmp(argv[1],"thread_mutex"))
3 lb = new lock_adapter<thread_mutex>(*(new thread_mutex));
4 else
5 lb = new lock_adapter<null_mutex> (*(new null_mutex));
6
auto_ptr<lock_base> ap(lb);
7
lock_guard<lock_base> guard(*lb);
8
//do some thing
2 if(argc>1 && 0==strcmp(argv[1],"thread_mutex"))
3 lb = new lock_adapter<thread_mutex>(*(new thread_mutex));
4 else
5 lb = new lock_adapter<null_mutex> (*(new null_mutex));
6

7

8
