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.

199 lines
3.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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)
}