You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

303 lines
5.1 KiB

package main
import (
"runtime"
"sync"
"time"
)
var wg sync.WaitGroup
func main() {
ch := make(chan int, 2)
ch <- 1
println("len, cap of channel:", len(ch), cap(ch), ch == nil)
ch = make(chan int)
println("len, cap of channel:", len(ch), cap(ch), ch == nil)
wg.Add(1)
go sender(ch)
n, ok := <-ch
println("recv from open channel:", n, ok)
for n := range ch {
println("received num:", n)
}
wg.Wait()
n, ok = <-ch
println("recv from closed channel:", n, ok)
// Test various channel size types.
_ = make(chan int, int8(2))
_ = make(chan int, int16(2))
_ = make(chan int, int32(2))
_ = make(chan int, int64(2))
_ = make(chan int, uint8(2))
_ = make(chan int, uint16(2))
_ = make(chan int, uint32(2))
_ = make(chan int, uint64(2))
// Test bigger values
ch2 := make(chan complex128)
wg.Add(1)
go sendComplex(ch2)
println("complex128:", <-ch2)
wg.Wait()
// Test multi-sender.
ch = make(chan int)
wg.Add(3)
go fastsender(ch, 10)
go fastsender(ch, 23)
go fastsender(ch, 40)
slowreceiver(ch)
wg.Wait()
// Test multi-receiver.
ch = make(chan int)
wg.Add(3)
go fastreceiver(ch)
go fastreceiver(ch)
go fastreceiver(ch)
slowsender(ch)
wg.Wait()
// Test iterator style channel.
ch = make(chan int)
wg.Add(1)
go iterator(ch, 100)
sum := 0
for i := range ch {
sum += i
}
wg.Wait()
println("sum(100):", sum)
// Test simple selects.
go selectDeadlock() // cannot use waitGroup here - never terminates
wg.Add(1)
go selectNoOp()
wg.Wait()
// Test select with a single send operation (transformed into chan send).
ch = make(chan int)
wg.Add(1)
go fastreceiver(ch)
select {
case ch <- 5:
}
close(ch)
wg.Wait()
println("did send one")
// Test select with a single recv operation (transformed into chan recv).
select {
case n := <-ch:
println("select one n:", n)
}
// Test select recv with channel that has one entry.
ch = make(chan int)
wg.Add(1)
go func(ch chan int) {
runtime.Gosched()
ch <- 55
wg.Done()
}(ch)
select {
case make(chan int) <- 3:
println("unreachable")
case <-(chan int)(nil):
println("unreachable")
case n := <-ch:
println("select n from chan:", n)
case n := <-make(chan int):
println("unreachable:", n)
}
wg.Wait()
// Test select recv with closed channel.
close(ch)
select {
case make(chan int) <- 3:
println("unreachable")
case n := <-ch:
println("select n from closed chan:", n)
case n := <-make(chan int):
println("unreachable:", n)
}
// Test select send.
ch = make(chan int)
wg.Add(1)
go fastreceiver(ch)
select {
case ch <- 235:
println("select send")
case n := <-make(chan int):
println("unreachable:", n)
}
close(ch)
wg.Wait()
// test non-concurrent buffered channels
ch = make(chan int, 2)
ch <- 1
ch <- 2
println("non-concurrent channel recieve:", <-ch)
println("non-concurrent channel recieve:", <-ch)
// test closing channels with buffered data
ch <- 3
ch <- 4
close(ch)
println("closed buffered channel recieve:", <-ch)
println("closed buffered channel recieve:", <-ch)
println("closed buffered channel recieve:", <-ch)
// test using buffered channels as regular channels with special properties
wg.Add(6)
ch = make(chan int, 2)
go send(ch)
go send(ch)
go send(ch)
go send(ch)
go receive(ch)
go receive(ch)
wg.Wait()
close(ch)
var count int
for range ch {
count++
}
println("hybrid buffered channel recieve:", count)
// test blocking selects
ch = make(chan int)
sch1 := make(chan int)
sch2 := make(chan int)
sch3 := make(chan int)
wg.Add(3)
go func() {
defer wg.Done()
time.Sleep(time.Millisecond)
sch1 <- 1
}()
go func() {
defer wg.Done()
time.Sleep(time.Millisecond)
sch2 <- 2
}()
go func() {
defer wg.Done()
// merge sch2 and sch3 into ch
for i := 0; i < 2; i++ {
var v int
select {
case v = <-sch1:
case v = <-sch2:
}
select {
case sch3 <- v:
panic("sent to unused channel")
case ch <- v:
}
}
}()
sum = 0
for i := 0; i < 2; i++ {
select {
case sch3 <- sum:
panic("sent to unused channel")
case v := <-ch:
sum += v
}
}
wg.Wait()
println("blocking select sum:", sum)
}
func send(ch chan<- int) {
ch <- 1
wg.Done()
}
func receive(ch <-chan int) {
<-ch
wg.Done()
}
func sender(ch chan int) {
for i := 1; i <= 8; i++ {
if i == 4 {
time.Sleep(time.Microsecond)
println("slept")
}
ch <- i
}
close(ch)
wg.Done()
}
func sendComplex(ch chan complex128) {
ch <- 7 + 10.5i
wg.Done()
}
func fastsender(ch chan int, n int) {
ch <- n
ch <- n + 1
wg.Done()
}
func slowreceiver(ch chan int) {
sum := 0
for i := 0; i < 6; i++ {
sum += <-ch
time.Sleep(time.Microsecond)
}
println("sum of n:", sum)
}
func slowsender(ch chan int) {
for n := 0; n < 6; n++ {
time.Sleep(time.Microsecond)
ch <- 12 + n
}
}
func fastreceiver(ch chan int) {
sum := 0
for i := 0; i < 2; i++ {
n := <-ch
sum += n
}
println("sum:", sum)
wg.Done()
}
func iterator(ch chan int, top int) {
for i := 0; i < top; i++ {
ch <- i
}
close(ch)
wg.Done()
}
func selectDeadlock() {
println("deadlocking")
select {}
println("unreachable")
}
func selectNoOp() {
println("select no-op")
select {
default:
}
println("after no-op")
wg.Done()
}