Я практикую параллельное программирование и приступил к реализации нескольких шаблонов и структур в go. Я также добавил тесты, в которых я использую семафор в качестве мьютекса для увеличения общего счетчика. Очевидно, что с моей реализацией что-то не так, потому что после запуска тестового файла несколько раз тесты проходят, а другие не проходят. Я предполагаю, что каким-то образом несколько потоков проходят вызов Wait () без блокировки и имеют параллельный доступ к переменной counter, но я не могу понять, почему. Любая помощь приветствуется!
семафор. go
package semaphore
import (
"sync"
)
type Semaphore struct {
capacity int
count int
sync.Mutex
condition chan bool
}
func (s *Semaphore) Wait() {
s.Lock()
defer s.Unlock()
if s.count == s.capacity {
s.Unlock()
<-s.condition
s.Lock()
}
s.count++
}
func (s *Semaphore) Signal() {
s.Lock()
defer s.Unlock()
select {
case s.condition <- true:
default:
}
s.count--
}
func NewSemaphore(n int) *Semaphore {
return &Semaphore{count: 0, capacity: n, condition: make(chan bool)}
}
семафор_test. go
package semaphore
import (
"sync"
"testing"
)
func TestMutexSemaphore(t *testing.T) {
s := NewSemaphore(1)
wg := sync.WaitGroup{}
sharedCounter := 0
iters := 25
n := 20
testfun := func(mutex *Semaphore) {
defer wg.Done()
for j := 0; j < iters; j++ {
s.Wait()
sharedCounter++
s.Signal()
}
}
wg.Add(n)
for i := 0; i < n; i++ {
go testfun(s)
}
wg.Wait()
if sharedCounter != iters*n {
t.Errorf("Bad counter value:%d expected %d", sharedCounter, n*iters)
}
}