testdata: replace fake waitgroup in channel.go with sync.WaitGroup
Этот коммит содержится в:
родитель
afc6bd5cdd
коммит
7801921cc0
1 изменённых файлов: 36 добавлений и 64 удалений
100
testdata/channel.go
предоставленный
100
testdata/channel.go
предоставленный
|
@ -2,45 +2,17 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// waitGroup is a small type reimplementing some of the behavior of sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
type waitGroup uint
|
|
||||||
|
|
||||||
func (wg *waitGroup) wait() {
|
|
||||||
n := 0
|
|
||||||
for *wg != 0 {
|
|
||||||
// pause and wait to be rescheduled
|
|
||||||
runtime.Gosched()
|
|
||||||
|
|
||||||
if n > 100 {
|
|
||||||
// if something is using the sleep queue, this may be necessary
|
|
||||||
time.Sleep(time.Millisecond)
|
|
||||||
}
|
|
||||||
|
|
||||||
n++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wg *waitGroup) add(n uint) {
|
|
||||||
*wg += waitGroup(n)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wg *waitGroup) done() {
|
|
||||||
if *wg == 0 {
|
|
||||||
panic("wait group underflow")
|
|
||||||
}
|
|
||||||
*wg--
|
|
||||||
}
|
|
||||||
|
|
||||||
var wg waitGroup
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
ch := make(chan int)
|
ch := make(chan int)
|
||||||
println("len, cap of channel:", len(ch), cap(ch), ch == nil)
|
println("len, cap of channel:", len(ch), cap(ch), ch == nil)
|
||||||
|
|
||||||
wg.add(1)
|
wg.Add(1)
|
||||||
go sender(ch)
|
go sender(ch)
|
||||||
|
|
||||||
n, ok := <-ch
|
n, ok := <-ch
|
||||||
|
@ -50,7 +22,7 @@ func main() {
|
||||||
println("received num:", n)
|
println("received num:", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.wait()
|
wg.Wait()
|
||||||
n, ok = <-ch
|
n, ok = <-ch
|
||||||
println("recv from closed channel:", n, ok)
|
println("recv from closed channel:", n, ok)
|
||||||
|
|
||||||
|
@ -66,55 +38,55 @@ func main() {
|
||||||
|
|
||||||
// Test bigger values
|
// Test bigger values
|
||||||
ch2 := make(chan complex128)
|
ch2 := make(chan complex128)
|
||||||
wg.add(1)
|
wg.Add(1)
|
||||||
go sendComplex(ch2)
|
go sendComplex(ch2)
|
||||||
println("complex128:", <-ch2)
|
println("complex128:", <-ch2)
|
||||||
wg.wait()
|
wg.Wait()
|
||||||
|
|
||||||
// Test multi-sender.
|
// Test multi-sender.
|
||||||
ch = make(chan int)
|
ch = make(chan int)
|
||||||
wg.add(3)
|
wg.Add(3)
|
||||||
go fastsender(ch, 10)
|
go fastsender(ch, 10)
|
||||||
go fastsender(ch, 23)
|
go fastsender(ch, 23)
|
||||||
go fastsender(ch, 40)
|
go fastsender(ch, 40)
|
||||||
slowreceiver(ch)
|
slowreceiver(ch)
|
||||||
wg.wait()
|
wg.Wait()
|
||||||
|
|
||||||
// Test multi-receiver.
|
// Test multi-receiver.
|
||||||
ch = make(chan int)
|
ch = make(chan int)
|
||||||
wg.add(3)
|
wg.Add(3)
|
||||||
go fastreceiver(ch)
|
go fastreceiver(ch)
|
||||||
go fastreceiver(ch)
|
go fastreceiver(ch)
|
||||||
go fastreceiver(ch)
|
go fastreceiver(ch)
|
||||||
slowsender(ch)
|
slowsender(ch)
|
||||||
wg.wait()
|
wg.Wait()
|
||||||
|
|
||||||
// Test iterator style channel.
|
// Test iterator style channel.
|
||||||
ch = make(chan int)
|
ch = make(chan int)
|
||||||
wg.add(1)
|
wg.Add(1)
|
||||||
go iterator(ch, 100)
|
go iterator(ch, 100)
|
||||||
sum := 0
|
sum := 0
|
||||||
for i := range ch {
|
for i := range ch {
|
||||||
sum += i
|
sum += i
|
||||||
}
|
}
|
||||||
wg.wait()
|
wg.Wait()
|
||||||
println("sum(100):", sum)
|
println("sum(100):", sum)
|
||||||
|
|
||||||
// Test simple selects.
|
// Test simple selects.
|
||||||
go selectDeadlock() // cannot use waitGroup here - never terminates
|
go selectDeadlock() // cannot use waitGroup here - never terminates
|
||||||
wg.add(1)
|
wg.Add(1)
|
||||||
go selectNoOp()
|
go selectNoOp()
|
||||||
wg.wait()
|
wg.Wait()
|
||||||
|
|
||||||
// Test select with a single send operation (transformed into chan send).
|
// Test select with a single send operation (transformed into chan send).
|
||||||
ch = make(chan int)
|
ch = make(chan int)
|
||||||
wg.add(1)
|
wg.Add(1)
|
||||||
go fastreceiver(ch)
|
go fastreceiver(ch)
|
||||||
select {
|
select {
|
||||||
case ch <- 5:
|
case ch <- 5:
|
||||||
}
|
}
|
||||||
close(ch)
|
close(ch)
|
||||||
wg.wait()
|
wg.Wait()
|
||||||
println("did send one")
|
println("did send one")
|
||||||
|
|
||||||
// Test select with a single recv operation (transformed into chan recv).
|
// Test select with a single recv operation (transformed into chan recv).
|
||||||
|
@ -125,11 +97,11 @@ func main() {
|
||||||
|
|
||||||
// Test select recv with channel that has one entry.
|
// Test select recv with channel that has one entry.
|
||||||
ch = make(chan int)
|
ch = make(chan int)
|
||||||
wg.add(1)
|
wg.Add(1)
|
||||||
go func(ch chan int) {
|
go func(ch chan int) {
|
||||||
runtime.Gosched()
|
runtime.Gosched()
|
||||||
ch <- 55
|
ch <- 55
|
||||||
wg.done()
|
wg.Done()
|
||||||
}(ch)
|
}(ch)
|
||||||
select {
|
select {
|
||||||
case make(chan int) <- 3:
|
case make(chan int) <- 3:
|
||||||
|
@ -141,7 +113,7 @@ func main() {
|
||||||
case n := <-make(chan int):
|
case n := <-make(chan int):
|
||||||
println("unreachable:", n)
|
println("unreachable:", n)
|
||||||
}
|
}
|
||||||
wg.wait()
|
wg.Wait()
|
||||||
|
|
||||||
// Test select recv with closed channel.
|
// Test select recv with closed channel.
|
||||||
close(ch)
|
close(ch)
|
||||||
|
@ -156,7 +128,7 @@ func main() {
|
||||||
|
|
||||||
// Test select send.
|
// Test select send.
|
||||||
ch = make(chan int)
|
ch = make(chan int)
|
||||||
wg.add(1)
|
wg.Add(1)
|
||||||
go fastreceiver(ch)
|
go fastreceiver(ch)
|
||||||
select {
|
select {
|
||||||
case ch <- 235:
|
case ch <- 235:
|
||||||
|
@ -165,7 +137,7 @@ func main() {
|
||||||
println("unreachable:", n)
|
println("unreachable:", n)
|
||||||
}
|
}
|
||||||
close(ch)
|
close(ch)
|
||||||
wg.wait()
|
wg.Wait()
|
||||||
|
|
||||||
// test non-concurrent buffered channels
|
// test non-concurrent buffered channels
|
||||||
ch = make(chan int, 2)
|
ch = make(chan int, 2)
|
||||||
|
@ -183,7 +155,7 @@ func main() {
|
||||||
println("closed buffered channel recieve:", <-ch)
|
println("closed buffered channel recieve:", <-ch)
|
||||||
|
|
||||||
// test using buffered channels as regular channels with special properties
|
// test using buffered channels as regular channels with special properties
|
||||||
wg.add(6)
|
wg.Add(6)
|
||||||
ch = make(chan int, 2)
|
ch = make(chan int, 2)
|
||||||
go send(ch)
|
go send(ch)
|
||||||
go send(ch)
|
go send(ch)
|
||||||
|
@ -191,7 +163,7 @@ func main() {
|
||||||
go send(ch)
|
go send(ch)
|
||||||
go receive(ch)
|
go receive(ch)
|
||||||
go receive(ch)
|
go receive(ch)
|
||||||
wg.wait()
|
wg.Wait()
|
||||||
close(ch)
|
close(ch)
|
||||||
var count int
|
var count int
|
||||||
for range ch {
|
for range ch {
|
||||||
|
@ -204,19 +176,19 @@ func main() {
|
||||||
sch1 := make(chan int)
|
sch1 := make(chan int)
|
||||||
sch2 := make(chan int)
|
sch2 := make(chan int)
|
||||||
sch3 := make(chan int)
|
sch3 := make(chan int)
|
||||||
wg.add(3)
|
wg.Add(3)
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.done()
|
defer wg.Done()
|
||||||
time.Sleep(time.Millisecond)
|
time.Sleep(time.Millisecond)
|
||||||
sch1 <- 1
|
sch1 <- 1
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.done()
|
defer wg.Done()
|
||||||
time.Sleep(time.Millisecond)
|
time.Sleep(time.Millisecond)
|
||||||
sch2 <- 2
|
sch2 <- 2
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.done()
|
defer wg.Done()
|
||||||
// merge sch2 and sch3 into ch
|
// merge sch2 and sch3 into ch
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
var v int
|
var v int
|
||||||
|
@ -240,18 +212,18 @@ func main() {
|
||||||
sum += v
|
sum += v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wg.wait()
|
wg.Wait()
|
||||||
println("blocking select sum:", sum)
|
println("blocking select sum:", sum)
|
||||||
}
|
}
|
||||||
|
|
||||||
func send(ch chan<- int) {
|
func send(ch chan<- int) {
|
||||||
ch <- 1
|
ch <- 1
|
||||||
wg.done()
|
wg.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
func receive(ch <-chan int) {
|
func receive(ch <-chan int) {
|
||||||
<-ch
|
<-ch
|
||||||
wg.done()
|
wg.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
func sender(ch chan int) {
|
func sender(ch chan int) {
|
||||||
|
@ -263,18 +235,18 @@ func sender(ch chan int) {
|
||||||
ch <- i
|
ch <- i
|
||||||
}
|
}
|
||||||
close(ch)
|
close(ch)
|
||||||
wg.done()
|
wg.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendComplex(ch chan complex128) {
|
func sendComplex(ch chan complex128) {
|
||||||
ch <- 7 + 10.5i
|
ch <- 7 + 10.5i
|
||||||
wg.done()
|
wg.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
func fastsender(ch chan int, n int) {
|
func fastsender(ch chan int, n int) {
|
||||||
ch <- n
|
ch <- n
|
||||||
ch <- n + 1
|
ch <- n + 1
|
||||||
wg.done()
|
wg.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
func slowreceiver(ch chan int) {
|
func slowreceiver(ch chan int) {
|
||||||
|
@ -300,7 +272,7 @@ func fastreceiver(ch chan int) {
|
||||||
sum += n
|
sum += n
|
||||||
}
|
}
|
||||||
println("sum:", sum)
|
println("sum:", sum)
|
||||||
wg.done()
|
wg.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
func iterator(ch chan int, top int) {
|
func iterator(ch chan int, top int) {
|
||||||
|
@ -308,7 +280,7 @@ func iterator(ch chan int, top int) {
|
||||||
ch <- i
|
ch <- i
|
||||||
}
|
}
|
||||||
close(ch)
|
close(ch)
|
||||||
wg.done()
|
wg.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
func selectDeadlock() {
|
func selectDeadlock() {
|
||||||
|
@ -323,5 +295,5 @@ func selectNoOp() {
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
println("after no-op")
|
println("after no-op")
|
||||||
wg.done()
|
wg.Done()
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче