Go基础知识梳理(四)

GO的哲学是“不要通过共享内存来通信,而是通过通信来共享内存”,通道是GO通过通信来共享内存的载体。

rumtime包常用方法

runtime.NumGoroutine() //返回当前程序的协程数量
runtime.GOMAXPROCS(0) //获取当前的GOMAXPROCS数量
runtime.GOMAXPROCS(2) //设置程序的GOMAXPROCS数量为2

goroutine

特性

  • 执行是非阻塞的,不会等待
  • go 后面的返回值会被忽略
  • 调度器不能保证goroutine的执行顺序
fun main() {
//另起一个协程去打印
go func() {
fmt.Println("goruntine")
}()
}

chan

//创建chan
c := make(chan dataType)
//无缓冲, len 和 cap 都是0
fmt.Println(len(c)) //0
fmt.Println(cap(c)) //0 //有缓冲
c = make(chan dataType, 10)
//len 代表没有被读取的元素数, cap 代表整个通道的容量
fmt.Println(len(c)) //0
fmt.Println(cap(c)) //10

WaitingGroup组件

Add(10) 给内置计数器加10

Done() 相当于Add(-1)

Wait() 内置计数器不为0则一直等待

// 写法
func main() {
var wg sync.WaitGroup
wg.Add(10)
for i := 0; i < 10; i++ {
go func(i int) {
defer wg.Done()
fmt.Println(i)
time.Sleep(time.Millisecond * 3000)
}(i)
}
wg.Wait()
fmt.Println("done")
}

select

  1. 先打乱所有的case语句
  2. 遍历case语句,查看是否已经读写了
  3. 选择可读写的case去执行
  4. 没有可读写的case,则查看default语句是否定义,再去执行
  5. 没有defaul语句,则会等待可执行的case

看一段融合了并发,缓冲,退出通知等多重特性的代码

func GenerateA(done chan struct{}) chan int {
ch := make(chan int, 5)
// fmt.Println("通道数+1")
go func() {
fmt.Println("线程数+A")
Label:
for {
select {
case res := <-done:
fmt.Println("done", res)
break Label
case ch <- rand.Int():
} }
close(ch)
}()
return ch
}
func GenerateB(done chan struct{}) chan int {
ch := make(chan int, 5)
go func() {
fmt.Println("线程数+B")
Label:
for {
select {
case res := <-done:
fmt.Println("done", res)
break Label
case ch <- rand.Int():
}
}
close(ch)
}()
return ch
} func GenerateInt(done chan struct{}) chan int {
//无缓冲通道
ch := make(chan int)
send := make(chan struct{})
go func() {
Label:
for { select {
case <-done:
send <- struct{}{}
send <- struct{}{}
break Label
case ch <- <-GenerateA(send):
fmt.Println("chose A")
case ch <- <-GenerateB(send):
fmt.Println("chose B")
}
}
close(ch)
}()
return ch
} func main() {
done := make(chan struct{})
ch := GenerateInt(done)
fmt.Println(runtime.NumGoroutine())
for i := 0; i < 10; i++ {
fmt.Println(<-ch)
}
fmt.Println(runtime.NumGoroutine())
done <- struct{}{}
fmt.Println("stop gernate", struct{}{})
time.Sleep(1 * time.Second) //等待1s,让停止的goruntime打印,如果不加这句话,可能会导致主线程比新起的协程早退出,从而无法打印出done {}
}

打印结果不展示,其中发现的问题:

1.打印出来的数字长度不固定

2.每次Select查看case是否堵塞的时候,都会执行一次该方法

Context

func main() {
ctxa, cancel := context.WithCancel(context.Background())
go work(ctxa, "work1")
tm := time.Now().Add(3 * time.Second)
ctxb, _ := context.WithDeadline(ctxa, tm)
go work(ctxb, "work2")
oc := OtherContext{ctxb}
ctxc := context.WithValue(oc, "key", "andes, pass from main")
go workWithValue(ctxc, "work3")
time.Sleep(10 * time.Second)
cancel()
time.Sleep(5 * time.Second)
fmt.Println("main stop") } type OtherContext struct {
context.Context
} func work(ctx context.Context, name string) {
for {
select {
case <-ctx.Done():
fmt.Printf("%s get msg to cancel\n", name)
return
default:
fmt.Printf("%s is running \n", name)
time.Sleep(1 * time.Second)
}
}
} func workWithValue(ctx context.Context, name string) {
for {
select {
case <-ctx.Done():
fmt.Printf("%s get msg to cancel\n", name)
return
default:
value := ctx.Value("key").(string)
fmt.Printf("%s is running value=%s \n", name, value)
time.Sleep(1 * time.Second)
}
}
}

这段代码中,都是一条链路下来的

根节点 context.Background() -> ctxa -> ctxb -> oc

其中ctxa加了个时间控制,所以到达一定的时间就会自动关闭

oc附带了个键对值

Go基础知识梳理(四)的更多相关文章

  1. [SQL] SQL 基础知识梳理(四) - 数据更新

    SQL 基础知识梳理(四) - 数据更新 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5929786.html 序 这是<SQL 基础知识梳理( ...

  2. [SQL] SQL 基础知识梳理(一)- 数据库与 SQL

    SQL 基础知识梳理(一)- 数据库与 SQL [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902856.html 目录 What's 数据库 ...

  3. [SQL] SQL 基础知识梳理(三) - 聚合和排序

    SQL 基础知识梳理(三) - 聚合和排序 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5926689.html 序 这是<SQL 基础知识梳理 ...

  4. [SQL] SQL 基础知识梳理(五) - 复杂查询

    SQL 基础知识梳理(五) - 复杂查询 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5939796.html 序 这是<SQL 基础知识梳理( ...

  5. C#基础知识梳理索引

    C#基础知识梳理索引 一 引子 之前曾写了一篇随笔<.NET平台技术体系梳理+初学者学习路径推荐+我们的愿景与目标> 三个月过去了,目标使更多的编程初学者,轻松高效地掌握C#开发的基础,重 ...

  6. [SQL] SQL 基础知识梳理(六)- 函数、谓词、CASE 表达式

    SQL 基础知识梳理(六)-  函数.谓词.CASE 表达式 目录 函数 谓词 CASE 表达式 一.函数 1.函数:输入某一值得到相应输出结果的功能,输入值称为“参数”,输出值称为“返回值”. 2. ...

  7. [SQL] SQL 基础知识梳理(七)- 集合运算

    SQL 基础知识梳理(七)- 集合运算 目录 表的加减法 联结(以列为单位) 一.表的加减法 1.集合:记录的集合(表.视图和查询的执行结果). 2.UNION(并集):表的加法 -- DDL:创建表 ...

  8. Linux基础知识梳理

    Linux基础知识梳理 Linux内核最初只是由芬兰人林纳斯?托瓦兹(Linus Torvalds)在赫尔辛基大学上学时出于个人爱好而编写的.Linux是一套免费使用和自由传播的类Unix操作系统,是 ...

  9. MySQL 基础知识梳理

    MySQL 的安装方式有多种,但是对于不同场景,会有最适合该场景的 MySQL 安装方式,下面就介绍一下 MySQL 常见的安装方法,包括 rpm 安装,yum 安装,通用二进制安装以及源码编译安装, ...

随机推荐

  1. python浮点数计算--5

    #!/usr/bin/python #coding=utf-8 i=1.0 j=3 print(i*j) print(i+j) print(i**j) 备注:无论是哪种运算,只要有操作数是浮点数,py ...

  2. JVM常用命令(九)

    前面东西说完后,现在可以说一些和我们平时进行性能调优相关的东西了,那怎么看和我们JVM性能调优相关的东西呢,其实这对我们开发来说是一个比较头痛的问题,其实我们JDK官网给了一些我们相关的指令,我们可以 ...

  3. RocketMQ在Windows和Linux下的安装

    windows下的RocketMQ的安装 鉴于Quick Start,选择单mater模式,环境简单: win10 64 jdk1.8 maven 3.5.4 Git rocketMQ安装版本 4.4 ...

  4. Docker版本Jenkins的使用

    一. 什么是Jenkins Jenkins是当前非常流行的一款持续集成工具,可以帮助大家把更新后的代码自动部署到服务器上运行. 二. 为什么用docker版的Jenkins Jenkins主要有三种安 ...

  5. nginx开发: 模块nginx_tcp_proxy_module

    nginx支持ws\wss连接,接入nginx_tcp_proxy_module模块 nginx版本1.14.2,在nginx_tcp_proxy_module模块中的上下行数据接口中处理数据解包与打 ...

  6. hitTest练习

    业务逻辑1:         底部一个按钮, 按钮的上面有一个View,遮挡在按钮的上面.         点击View时, View接收事件,当发现点击的点在按钮的位置时, 让底部的按钮处理事件. ...

  7. 7.3php编译安装最终版

    进过无数次折腾后发现编译php安装的有些难, 问题可能是自己对linux不太了解吧. [root@third src]# cd php-7.3.6 [root@third php-7.3.6]# ./ ...

  8. 计算机网络再次整理————tcp周边[八]

    前言 tcp的包的格式可以看我以前的计算机网络整理,下面这些周边只是为了开发时候我们能用到一些理论知识. 正文 首先要介绍的就是域名,为啥有域名这东西呢?单纯站在网络的角度上讲这属于应用层的东西了. ...

  9. Solution -「ARC 063D」「AT 2149」Snuke's Coloring 2

    \(\mathcal{Decription}\)   Link.   平面上有一个左下角坐标 \((0,0)\) 右上角坐标 \((W,H)\) 的矩形,起初长方形内部被涂白. 现在给定 \(n\) ...

  10. Sunlogin RCE漏洞分析和使用

    介绍   前两天网上曝出了关于向日葵远控工具(Sunlogin)Windows个人版的RCE漏洞POC.因为利用简单并且网上出现了公开的自动化扫描脚本,所以测试的人很多,也出现了一些真实攻击.漏洞的问 ...