Advertisement
den4ik2003

Untitled

Oct 31st, 2023
730
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 3.11 KB | None | 0 0
  1. //go:build !solution
  2.  
  3. package rwmutex
  4.  
  5. import "sync/atomic"
  6.  
  7. // A RWMutex is a reader/writer mutual exclusion lock.
  8. // The lock can be held by an arbitrary number of readers or a single writer.
  9. // The zero value for a RWMutex is an unlocked mutex.
  10. //
  11. // If a goroutine holds a RWMutex for reading and another goroutine might
  12. // call Lock, no goroutine should expect to be able to acquire a read lock
  13. // until the initial read lock is released. In particular, this prohibits
  14. // recursive read locking. This is to ensure that the lock eventually becomes
  15. // available; a blocked Lock call excludes new readers from acquiring the
  16. // lock.
  17. type RWMutex struct {
  18.     readerSem   chan struct{}
  19.     writerSem   chan struct{}
  20.     readerCount atomic.Int32
  21. }
  22.  
  23. // New creates *RWMutex.
  24. func New() *RWMutex {
  25.     rSem := make(chan struct{}, 1)
  26.     wrSem := make(chan struct{}, 1)
  27.     return &RWMutex{rSem, wrSem, atomic.Int32{}}
  28. }
  29.  
  30. // RLock locks rw for reading.
  31. //
  32. // It should not be used for recursive read locking; a blocked Lock
  33. // call excludes new readers from acquiring the lock. See the
  34. // documentation on the RWMutex type.
  35. func (rw *RWMutex) RLock() { // мы по сути под мьютексом это делаем
  36.     rw.writerSem <- struct{}{} // error
  37.     rw.readerCount.Add(1)
  38.  
  39.     select { // обозначили, что есть читатели
  40.     case rw.readerSem <- struct{}{}:
  41.     default:
  42.     }
  43.  
  44.     <-rw.writerSem
  45. }
  46.  
  47. // RUnlock undoes a single RLock call;
  48. // it does not affect other simultaneous readers.
  49. // It is a run-time error if rw is not locked for reading
  50. // on entry to RUnlock.
  51. func (rw *RWMutex) RUnlock() {
  52.     select {
  53.     case rw.writerSem <- struct{}{}: // Если RLock владеет, то он быстро отдаст; если Lock, то долго стоим
  54.         if readersRemain := rw.readerCount.Add(-1); readersRemain == 0 {
  55.             <-rw.readerSem
  56.             <-rw.writerSem
  57.         }
  58.     default:
  59.         if readersRemain := rw.readerCount.Add(-1); readersRemain == 0 {
  60.             <-rw.readerSem
  61.         }
  62.     }
  63.  
  64. }
  65.  
  66. // Lock locks rw for writing.
  67. // If the lock is already locked for reading or writing,
  68. // Lock blocks until the lock is available.
  69. func (rw *RWMutex) Lock() {
  70.     rw.writerSem <- struct{}{} // error
  71.     rw.readerSem <- struct{}{}
  72.     // <-rw.readerSem // in unlock now
  73. }
  74.  
  75. // Unlock unlocks rw for writing. It is a run-time error if rw is
  76. // not locked for writing on entry to Unlock.
  77. //
  78. // As with Mutexes, a locked RWMutex is not associated with a particular
  79. // goroutine. One goroutine may RLock (Lock) a RWMutex and then
  80. // arrange for another goroutine to RUnlock (Unlock) it.
  81. func (rw *RWMutex) Unlock() {
  82.     <-rw.readerSem
  83.     <-rw.writerSem
  84. }
  85.  
  86. // TODO: 2 ридера сделали RLock, далее врайтер сделал Lock, после этого если придёт ридер, то он исполнится после врайтера
  87. // Когда в очереди есть писатель, то читатели блочатся
  88.  
  89. // В RUnlock мы иногда могли выпихнуть <-rw.writersSem, когда там ждал писатель
  90.  
  91. // 1) RLock
  92. // 2) Lock
  93. // 3) 100 x RLock
  94. // 4) RUnlock
  95.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement