【发布时间】:2020-04-24 15:07:11
【问题描述】:
我正在练习并发编程,并且已经着手在 go 中实现几种模式和结构。我还添加了测试,其中我将信号量用作互斥体以增加共享计数器。我的实现显然有问题,因为在运行了几次测试文件后,一些测试通过了,而另一些则失败了。 我的猜测是,不知何故,多个线程在没有阻塞的情况下通过了 Wait() 调用,并且可以并发访问 counter 变量,但我不知道为什么。任何帮助表示赞赏!
semaphore.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)}
}
semaphore_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)
}
}
【问题讨论】:
标签: go concurrency mutex semaphore shared-memory