为了账号安全,请及时绑定邮箱和手机立即绑定

GO学习笔记5-实现并发

标签:
Go

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数据

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
全栈工程师
手记
粉丝
11
获赞与收藏
43

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消