-
Notifications
You must be signed in to change notification settings - Fork 1
/
lock.py
166 lines (138 loc) · 4.32 KB
/
lock.py
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# -*- coding: utf-8 -*-
import threading
class Source:
# 队列成员标识
__N = None
__isFair = False
# 排他锁
__X = 0
# 意向排他锁
__IX = 1
# 共享锁标识
__S = 2
# 意向共享标识
__IS = 3
# 同步排他锁
__lockX = threading.Lock()
# 事件通知
__events = [
threading.Event(),
threading.Event(),
threading.Event(),
threading.Event()
]
# 事件通知队列
__eventsQueue = [
[],
[],
[],
[]
]
# 事件变更锁
__eventsLock = [
threading.Lock(),
threading.Lock(),
threading.Lock(),
threading.Lock()
]
# 相互互斥的锁
__mutexFlag = {}
# 锁类
class __ChildLock:
# 锁标识
__flag = 0
# 锁定的资源
__source = None
def __init__(self, source, flag):
self.__flag = flag
self.__source = source
# 加锁
def lock(self):
self.__source.lock(self.__flag)
# 解锁
def unlock(self):
self.__source.unlock(self.__flag)
def __init__(self, isFair=False):
self.__isFair = isFair
self.__initMutexFlag()
self.__initEvents()
# 不建议直接在外面使用,以免死锁
def lock(self, flag):
# 如果是排他锁,先进进行枷锁
if flag == self.__X: self.__lockX.acquire()
if self.__isFair:
# 如果是公平锁则,先将互斥的锁给阻塞,防止其他线程进入
self.__lockEventsWait(flag)
self.__events[flag].wait()
self.__lockEventsQueue(flag)
else:
# 如果是非公平锁,如果锁拿不到,则先等待
self.__events[flag].wait()
self.__lockEvents(flag)
# 不建议直接在外面使用,以免死锁
def unlock(self, flag):
self.__unlockEvents(flag)
if flag == self.__X: self.__lockX.release()
# 获取相互互斥
def __getMutexFlag(self, flag):
return self.__mutexFlag[flag]
def __initMutexFlag(self):
self.__mutexFlag[self.__X] = [self.__X, self.__IX, self.__S, self.__IS]
self.__mutexFlag[self.__IX] = [self.__X, self.__S]
self.__mutexFlag[self.__S] = [self.__X, self.__IX]
self.__mutexFlag[self.__IS] = [self.__X]
def __initEvents(self):
for event in self.__events:
event.set()
# 给事件加锁, 调用 wait 时阻塞
def __lockEvents(self, flag):
mutexFlags = self.__getMutexFlag(flag)
for i in mutexFlags:
# 为了保证原子操作,加锁
self.__eventsLock[i].acquire()
self.__eventsQueue[i].append(self.__N)
self.__events[i].clear()
self.__eventsLock[i].release()
# 给事件加锁等待
def __lockEventsWait(self, flag):
mutexFlags = self.__getMutexFlag(flag)
for i in mutexFlags:
# 为了保证原子操作,加锁
self.__eventsLock[i].acquire()
self.__events[i].clear()
self.__eventsLock[i].release()
# 加入队列标识
def __lockEventsQueue(self, flag):
mutexFlags = self.__getMutexFlag(flag)
for i in mutexFlags:
# 为了保证原子操作,加锁
self.__eventsLock[i].acquire()
self.__eventsQueue[i].append(self.__N)
self.__eventsLock[i].release()
# 给事件解锁, 调用 wait 不阻塞
def __unlockEvents(self, flag):
mutexFlags = self.__getMutexFlag(flag)
for i in mutexFlags:
# 为了保证原子操作,加锁
self.__eventsLock[i].acquire()
self.__eventsQueue[i].pop(0)
if len(self.__eventsQueue[i]) == 0:
self.__events[i].set()
self.__eventsLock[i].release()
# 获取锁
def __getLock(self, flag):
lock = self.__ChildLock(self, flag)
lock.lock()
return lock
# 获取 X 锁
def lockX(self):
return self.__getLock(self.__X)
# 获取 IX 锁
def lockIX(self):
return self.__getLock(self.__IX)
# 获取 S 锁
def lockS(self):
return self.__getLock(self.__S)
# 获取 IS 锁
def lockIS(self):
return self.__getLock(self.__IS)