|
|
package goConcurrency
|
|
|
|
|
|
import (
|
|
|
"fmt"
|
|
|
"math/rand"
|
|
|
"runtime"
|
|
|
"sync"
|
|
|
"time"
|
|
|
)
|
|
|
|
|
|
func ChannelOperate() {
|
|
|
// 初始化
|
|
|
ch := make(chan int) // 无缓冲的channel
|
|
|
|
|
|
// send
|
|
|
go func() {
|
|
|
// send statement 发送语句
|
|
|
ch <- 42 + 1024
|
|
|
}()
|
|
|
|
|
|
// receive
|
|
|
go func() {
|
|
|
// receive operation, 接收操作符
|
|
|
v := <-ch
|
|
|
println("Received from ch, value is ", v)
|
|
|
}()
|
|
|
|
|
|
time.Sleep(time.Second)
|
|
|
|
|
|
// close
|
|
|
close(ch)
|
|
|
}
|
|
|
|
|
|
func ChannelFor() {
|
|
|
// 一,初始化部分数据
|
|
|
ch := make(chan int) // 无缓冲的channel
|
|
|
wg := sync.WaitGroup{}
|
|
|
|
|
|
// 二,持续发送
|
|
|
wg.Add(1)
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
for i := 0; i < 5; i++ {
|
|
|
// random send value
|
|
|
ch <- rand.Intn(10)
|
|
|
}
|
|
|
// 关闭
|
|
|
close(ch)
|
|
|
}()
|
|
|
|
|
|
// 三,持续接收,for range
|
|
|
wg.Add(1)
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
// 持续接收
|
|
|
for e := range ch {
|
|
|
println("received from ch, element is ", e)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
wg.Wait()
|
|
|
}
|
|
|
|
|
|
func ChannelSync() {
|
|
|
// 初始化内容
|
|
|
ch := make(chan int)
|
|
|
println("Len:", len(ch), ",Cap:", cap(ch))
|
|
|
wg := sync.WaitGroup{}
|
|
|
|
|
|
// 二,间隔发送
|
|
|
wg.Add(1)
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
for i := 0; i < 5; i++ {
|
|
|
// send to ch
|
|
|
ch <- i
|
|
|
// .Format(layout) 格式化时间
|
|
|
println("Send ", i, ".\tNow:", time.Now().Format("15:04:05.999999999"))
|
|
|
// 间隔时间
|
|
|
time.Sleep(1 * time.Second)
|
|
|
}
|
|
|
// close channel
|
|
|
close(ch)
|
|
|
}()
|
|
|
|
|
|
// 三,间隔接收
|
|
|
wg.Add(1)
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
// receive from ch
|
|
|
// until ch closed
|
|
|
for v := range ch {
|
|
|
println("Received ", v, ".\tNow:", time.Now().Format("15:04:05.999999999"))
|
|
|
// 间隔时间,注意与send的间隔时间不同
|
|
|
time.Sleep(3 * time.Second)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
//
|
|
|
wg.Wait()
|
|
|
}
|
|
|
|
|
|
func ChannelAsync() {
|
|
|
// 初始化内容
|
|
|
ch := make(chan int, 5)
|
|
|
println("Len:", len(ch), ",Cap:", cap(ch))
|
|
|
wg := sync.WaitGroup{}
|
|
|
|
|
|
// 二,间隔发送
|
|
|
wg.Add(1)
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
for i := 0; i < 5; i++ {
|
|
|
// send to ch
|
|
|
ch <- i
|
|
|
// .Format(layout) 格式化时间
|
|
|
println("Send ", i, ".\tNow:", time.Now().Format("15:04:05.999999999"), ".Len:", len(ch), ",Cap:", cap(ch))
|
|
|
// 间隔时间
|
|
|
time.Sleep(1 * time.Second)
|
|
|
}
|
|
|
// close channel
|
|
|
close(ch)
|
|
|
}()
|
|
|
|
|
|
// 三,间隔接收
|
|
|
wg.Add(1)
|
|
|
go func() {
|
|
|
defer wg.Done()
|
|
|
// receive from ch
|
|
|
// until ch closed
|
|
|
for v := range ch {
|
|
|
println("Received ", v, ".\tNow:", time.Now().Format("15:04:05.999999999"), ".Len:", len(ch), ",Cap:", cap(ch))
|
|
|
// 间隔时间,注意与send的间隔时间不同
|
|
|
time.Sleep(3 * time.Second)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
//
|
|
|
wg.Wait()
|
|
|
}
|
|
|
|
|
|
func ChannelGoroutineNumCtl() {
|
|
|
// 1 独立的goroutine输出goroutine数量
|
|
|
go func() {
|
|
|
for {
|
|
|
fmt.Println("NumGoroutine:", runtime.NumGoroutine())
|
|
|
time.Sleep(500 * time.Millisecond)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
// 2 初始化channel,设置缓冲大小(并发规模)
|
|
|
const size = 1024
|
|
|
ch := make(chan struct{}, size)
|
|
|
|
|
|
// 3 并发的goroutine
|
|
|
for {
|
|
|
// 一,启动goroutine前,执行 ch send
|
|
|
// 当ch的缓冲已满时,阻塞
|
|
|
ch <- struct{}{}
|
|
|
go func() {
|
|
|
time.Sleep(10 * time.Second)
|
|
|
// 二,goroutine结束时,接收一个ch中的元素
|
|
|
<-ch
|
|
|
}()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func ChannelDirectional() {
|
|
|
// 初始化数据
|
|
|
ch := make(chan int) // 双向的channel
|
|
|
wg := &sync.WaitGroup{} // *sync.WaitGroup
|
|
|
|
|
|
// 单向channel函数go调用
|
|
|
wg.Add(2)
|
|
|
// 使用双向channel为单向channel赋值
|
|
|
go getElement(ch, wg)
|
|
|
go setElement(ch, 42, wg)
|
|
|
|
|
|
//
|
|
|
wg.Wait()
|
|
|
}
|
|
|
|
|
|
// only receive channel
|
|
|
// 语法即注释,使程序更加优雅
|
|
|
func getElement(ch <-chan int, wg *sync.WaitGroup) {
|
|
|
defer wg.Done()
|
|
|
//ch <- 10, 限制该操作不能执行
|
|
|
|
|
|
println("received from ch, element is ", <-ch)
|
|
|
}
|
|
|
|
|
|
// only send channel
|
|
|
func setElement(ch chan<- int, v int, wg *sync.WaitGroup) {
|
|
|
defer wg.Done()
|
|
|
// <-ch 限制该操作不能执行
|
|
|
ch <- v
|
|
|
println("send to ch, element is ", v)
|
|
|
}
|