测试信号量实现时出错



我正在练习并发编程,我已经着手在go中实现几个模式和结构。我还添加了一些测试,在这些测试中,我使用信号量作为Mutex来增加共享计数器。我的实现显然有问题,因为在运行了几次测试文件之后,有些测试通过了,而另一些则失败了。我的猜测是,不知何故,多个线程可以在没有阻塞的情况下通过Wait((调用,并可以并发访问计数器变量,但我不知道为什么。感谢您的帮助!

信号量.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)}
}

信号量_测试.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)
}
}

Wait中,当您醒来并锁定时,不能保证条件仍然成立。锁定后,您应该再次检查条件:

for s.count == s.capacity {
s.Unlock()
<-s.condition
s.Lock()
}

Signal中,你应该先count--,然后再叫醒其他人。

最新更新