测试信号量实现时出错
Error when testing semaphore implementation
我正在练习并发编程,我已经着手在 go 中实现多种模式和结构。我还添加了测试,其中我将信号量用作互斥量以增加共享计数器。我的实现显然有问题,因为在 运行 测试文件几次之后,一些测试通过了,但另一些测试失败了。
我的猜测是,不知何故,多个线程在没有阻塞的情况下通过了 Wait() 调用,并且可以并发访问计数器变量,但我不知道为什么。感谢您的帮助!
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)
}
}
在Wait
中,当您唤醒并锁定时,无法保证条件仍然成立。锁定后,您应该再次检查条件:
for s.count == s.capacity {
s.Unlock()
<-s.condition
s.Lock()
}
在Signal
你应该count--
在叫醒别人之前。
我正在练习并发编程,我已经着手在 go 中实现多种模式和结构。我还添加了测试,其中我将信号量用作互斥量以增加共享计数器。我的实现显然有问题,因为在 运行 测试文件几次之后,一些测试通过了,但另一些测试失败了。 我的猜测是,不知何故,多个线程在没有阻塞的情况下通过了 Wait() 调用,并且可以并发访问计数器变量,但我不知道为什么。感谢您的帮助!
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)
}
}
在Wait
中,当您唤醒并锁定时,无法保证条件仍然成立。锁定后,您应该再次检查条件:
for s.count == s.capacity {
s.Unlock()
<-s.condition
s.Lock()
}
在Signal
你应该count--
在叫醒别人之前。