package main
import (
. "fmt" //打印使用包
"runtime" //并发
"time" //时间延后
)
func say(s string) {
//runtime.Gosched()表示让CPU把时间片让给别人,下次某个时候继续恢复执行该goroutine。
for i := 0; i < 3; i++ {
//让出当前goroutine的执行权限,调度器安排其他等待的任务运行,并在下次某个时候从该位置恢复执行。
runtime.Gosched()
Println(s)
//runtime.Goexit() // 退出当前执行的goroutine,但是defer函数还会继续调用
}
}
func main() {
//开一个新的Goroutines执行
go say("1")
//当前Goroutines执行
say("2")
//调换顺序,显示的只有4,没有3
say("4")
go say("3")
a := []int{7, 2, 8, -9, 4, 0}
//channels的初始化
c := make(chan int)
Println("长度为:", len(a)/2)
go sum(a[:len(a)/2], c) //操作的值是:7,2,8
go sum(a[len(a)/2:], c) //操作的值是:-9,4,0
x, y := <-c, <-c //读取操作的结果
Println("第一个值:", x, "第二个值为:", y, "相加的结果为:", x+y)
go sum(a[:], c)
z := <-c
Println("全部数相加的和值:", z)
//ch := make(chan type, value)
//value == 0 //无缓冲(阻塞)
//value > 0 // 缓冲(非阻塞,直到value 个元素)
d := make(chan int, 4) //修改2为1就报错,修改2为3可以正常运行
d <- 1
d <- 2
d <- 3
Println(<-d)
Println(<-d)
Println(<-d)
e := make(chan int, 10)
go fibonacci(cap(e), e)
//range e能够不断的读取channel里面的数据,直到该channel被显式的关闭
for i := range e {
Println("函数值:", i)
}
//通过select执行多个channel
//select默认是阻塞的,只有当监听的channel中有发送或接收可以进行时才会运行,
//当多个channel都准备好的时候,select是随机的选择一个执行的
f := make(chan int)
quit := make(chan int)
go func() {
for i := 0; i < 10; i++ {
Println("AAA:", <-f)
}
quit <- 0
}()
TestAA(f, quit)
//延时
g := make(chan int, 3)
g <- 25
g <- 24
g <- 23
o := make(chan bool)
go func() {
for {
select {
case v := <-g:
println("BBB:", v)
case <-time.After(2 * time.Second): //2秒后执行下面的操作
println("timeout")
o <- true
break
}
}
}()
<-o
//
nn := runtime.NumCPU() //CPU 核数量
Println("总合数:", nn)
mm := runtime.NumGoroutine() //返回正在执行和排队的任务总数
Println("任务总数:", mm)
pp := runtime.GOMAXPROCS(mm) //用来设置可以运行的CPU核数
Println("CPU核数:", pp)
}
//使用channels
//默认情况下,channel接收和发送数据都是阻塞的,除非另一端已经准备好,这样就使得
//Goroutines同步变的更加的简单,而不需要显式的lock。所谓阻塞,也就是如果读取
//(value := <-ch)它将会被阻塞,直到有数据接收。其次,任何发送(ch<-5)将会被阻塞,
//直到数据被读出。无缓冲channel是在多个goroutine之间同步很棒的工具。
func sum(a []int, c chan int) {
sum := 0
for _, v := range a {
sum += v
}
c <- sum // send sum to c
}
//range和close
func fibonacci(n int, c chan int) {
x, y := 1, 1
for i := 0; i < n; i++ {
c <- x
x, y = y, x+y
}
//close函数关闭channel
close(c)
}
//使用select
func TestAA(c, quit chan int) {
x, y := 1, 1
for {
select {
case c <- x:
x, y = y, x+y
case <-quit:
Println("quit")
return
}
}
}
//var和const Go语言基础里面的变量和常量申明
// package和import 引入包
// func 用于定义函数和方法
// return 用于从函数返回
// defer 用于类似析构函数
// go 用于并行
// select 用于选择不同类型的通讯
// interface 用于定义接口
// struct 用于定义抽象数据类型
// break、case、continue、for、fallthrough、else、if、switch、goto、default //逻辑操作
// chan用于channel 通讯
// type 用于声明自定义类型
// map 用于声明map类型数据
// range用于读取slice、map、channel数据