i need read\write lock application. i've read https://en.wikipedia.org/wiki/readers%e2%80%93writer_lock
and wrote own class, cause there no read/write lock in swift
class readwritelock { var logging = true var b = 0 let r = "vdsbsdbs" // string1 locking let g = "vsdbvsdbsdbnsdn" // string2 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) } } }
it works good, until try use gcd threads.
dispatch_async(dispatch_get_global_queue(dispatch_queue_priority_low, 0) dispatch_async(dispatch_get_global_queue(dispatch_queue_priority_default, 0)
when try use class different async blocks @ moment allows write when write locked
here sample log:
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
so, can see g locked, objc_sync_enter(g) allows continue. why happen ?
btw checked how many times readwritelock constructed, , it's 1.
why objc_sync_exit not working , allowing objc_sync_enter(g) when it's not freed ?
ps readwirtelock defined
class userdata { static let lock = readwritelock()
thanks.
objc_sync_enter
extremely low-level primitive, , isn't intended used directly. it's implementation detail of old @synchronized
system in objc. extremely out-dated , should avoided.
synchronized access in cocoa best achieved gcd queues. example, common approach achieves reader/writer lock (concurrent reading, exclusive writing).
public class userdata { private let mypropertyqueue = dispatch_queue_create("com.example.mygreatapp.property", dispatch_queue_concurrent) private var _myproperty = "" // backing storage public var myproperty: string { { var result = "" dispatch_sync(mypropertyqueue) { result = self._myproperty } return result } set { dispatch_barrier_async(mypropertyqueue) { self._myproperty = newvalue } } } }
all concurrent properties can share single queue, or can give each property own queue. depends on how contention expect (a writer lock entire queue).
the "barrier" in "dispatch_barrier_async" means thing allowed run on queue @ time, previous reads have completed, , future reads prevented until completes. scheme means can have many concurrent readers want without starving writers (since writers serviced), , writes never blocking. on reads blocking, , if there actual contention. in normal, uncontested case, extremely fast.
Comments
Post a Comment