Advertisement
den4ik2003

Untitled

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