Мне нужно чтение\запись для моего приложения. Я прочитал https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock
и написал мой собственный класс, потому что в Swift нет блокировки чтения/записи
class ReadWriteLock {
var logging = true
var b = 0
let r = "vdsbsdbs" // string1 for locking
let g = "VSDBVSDBSDBNSDN" // string2 for locking
func waitAndStartWriting() {
log("wait Writing")
objc_sync_enter(g)
log("enter writing")
}
func finishWriting() {
objc_sync_exit(g)
log("exit writing")
}
// ждет пока все чтение завершится чтобы начать чтение
// и захватить мютекс
func waitAndStartReading() {
log("wait reading")
objc_sync_enter(r)
log("enter reading")
b++
if b == 1 {
objc_sync_enter(g)
log("read lock writing")
}
print("b = \(b)")
objc_sync_exit(r)
}
func finishReading() {
objc_sync_enter(r)
b--
if b == 0 {
objc_sync_exit(g)
log("read unlock writing")
}
print("b = \(b)")
objc_sync_exit(r)
}
private func log(s: String) {
if logging {
print(s)
}
}
}
Он работает хорошо, пока я не попытаюсь использовать его из потоков GCD.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
Когда я пытаюсь использовать этот класс из разных асинхронных блоков, в какой-то момент он позволяет писать, когда запись заблокирована
Вот пример журнала:
wait reading
enter reading
read lock writing
b = 1
wait reading
enter reading
b = 2
wait reading
enter reading
b = 3
wait reading
enter reading
b = 4
wait reading
enter reading
b = 5
wait reading
enter reading
b = 6
wait reading
enter reading
b = 7
wait reading
enter reading
b = 8
wait reading
enter reading
b = 9
b = 8
b = 7
b = 6
b = 5
wait Writing
enter writing
exit writing
wait Writing
enter writing
Итак, как вы видите, g заблокирован, но objc_sync_enter (g) позволяет продолжить. Почему это может случиться?
Кстати, я проверил, сколько раз построил ReadWriteLock, и он 1.
Почему objc_sync_exit не работает и разрешает objc_sync_enter (g), когда он не освобожден?
PS Readwirtelock определяется как
class UserData {
static let lock = ReadWriteLock()
Спасибо.