concurrency - goroutine blocks when calling RWMutex RLock twice after an RWMutex Unlock -
var mu sync.rwmutex go func() { mu.rlock() defer mu.runlock() mu.rlock() // in real scenario second lock happened in nested function. defer mu.runlock() // more code. }() mu.lock() mu.unlock() // goroutine above still hangs. if function read-locks read/write mutex twice, while function write-locks , write-unlocks same mutex, original function still hangs.
why that? because there's serial order in mutexes allow code execute?
i've solved scenario (which took me hours pinpoint) removing second mu.rlock() line.
this 1 of several standard behaviours read-write lock. wikipedia calls "write-preferring rw locks".
the documentation sync's rwmutex.lock says:
to ensure lock becomes available, blocked lock call excludes new readers acquiring lock.
otherwise series of readers each acquired read lock before previous released starve out writes indefinitely.
this means unsafe call rlock on rwmutex same goroutine has read locked. (which way true of lock on regular mutexes well, go's mutexes not support recursive locking.)
the reason unsafe if goroutine ever blocks getting second read lock (due blocked writer) never release first read lock. cause every future lock call on mutex block forever, deadlocking part or of program. go detect deadlock if goroutines blocked.
Comments
Post a Comment