Go基础知识梳理(四)

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("&#x901A;&#x9053;&#x6570;+1")
    go func() {
        fmt.Println("&#x7EBF;&#x7A0B;&#x6570;+A")
    Label:
        for {
            select {
            case res := <-done: fmt.println("done", res) break label case ch <- rand.int(): } close(ch) }() return func generateb(done chan struct{}) int { :="make(chan" int, 5) go func() fmt.println("线程数+b") label: for select res generateint(done 无缓冲通道 int) send <-done: struct{}{} <-generatea(send): fmt.println("chose a") <-generateb(send): b") main() done fmt.println(runtime.numgoroutine()) i < 10; i++ fmt.println(<-ch) fmt.println("stop gernate", struct{}{}) time.sleep(1 * time.second) 等待1s,让停止的goruntime打印,如果不加这句话,可能会导致主线程比新起的协程早退出,从而无法打印出done {} code></-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: is running \n", time.sleep(1 * time.second) } func workwithvalue(ctx context.context, name string) { for select case <-ctx.done(): value :="ctx.Value("key").(string)" name, value) < code></-ctx.done():>

这段代码中,都是一条链路下来的
根节点 context.Background() -> ctxa -> ctxb -> oc
其中ctxa加了个时间控制,所以到达一定的时间就会自动关闭
oc附带了个键对值

Original: https://www.cnblogs.com/xiaofua/p/15870609.html
Author: 小傅啊
Title: Go基础知识梳理(四)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/516446/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Go微服务框架-2.Go语言RPC编程实践

    Go语言实现RPC编程 上节课我们对RPC知识做了介绍,讲解了RPC的原理,通过图示方式讲解了RPC的内部执行过程。本节课,我们继续来学习RPC相关的内容。 在Go语言官方网站的p…

    Go语言 2023年5月29日
    058
  • Go语言实现线程安全访问队列

    这个例子用Go语言的包”container/list”实现一个线程安全访问的队列。其中不少细节耐人寻味,做出它则是花费了不少精力,找不到样例啊! Go语言的…

    Go语言 2023年5月29日
    045
  • Go语言基础之并发

    并发是编程里面一个非常重要的概念,Go语言在语言层面天生支持并发,这也是Go语言流行的一个很重要的原因。 Go语言中的并发编程 并发与并行 并发:同一时间段内执行多个任务(你在用微…

    Go语言 2023年5月29日
    048
  • go-micro开发RPC服务的方法及其运行原理

    go-micro是一个知名的golang微服务框架,最新版本是v4,这篇文章将介绍go-micro v4开发RPC服务的方法及其运作原理。 基本概念 go-micro有几个重要的概…

    Go语言 2023年5月25日
    050
  • go语言标准库

    学习go 语言,如果不知道标准库,那很多能力就不知道,标准库应该是程序员可以背下来的 bufio bytes container crypto database debug enc…

    Go语言 2023年5月29日
    053
  • Go语言之数组与切片基础

    数组是同一类型元素的集合,可以放多个值,但是类型一致,内存中连续存储 Go 语言中不允许混合不同类型的元素,而且数组的大小,在定义阶段就确定了,不能更改 1、数组的定义 // 定义…

    Go语言 2023年5月25日
    066
  • Go语言实现大数开方程序

    Go语言的big包实现大数运算,但是有关大整数运算,似乎没有相应的开方程序。 这里给出的程序,实现了大整数的开方运算函数。该程序是基于大整数开方运算的算法实现的。 Go语言程序: …

    Go语言 2023年5月29日
    057
  • 从零开始搭建GoLang语言开发环境

    更多干货文章,更多最新文章,欢迎到作者主博客 菜鸟厚非 一、安装 GoLang 1.1 下载 首先访问 https://go.dev/dl/ 下载 GoLang,下载完成后双击安装…

    Go语言 2023年5月25日
    063
  • GO语言 文件操作实例

    package main import ( "bufio" "fmt" "io/ioutil" "os&quo…

    Go语言 2023年5月29日
    047
  • Excelize 发布 2.6.0 版本,功能强大的 Excel 文档基础库

    Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准。可以使用它来读取、写入由 Mic…

    Go语言 2023年5月25日
    076
  • golang多版本管理工具

    前言 以往我安装 go环境都是去网站上下载对应文件,然后本地解压。每次发布新版本都这样做太麻烦了,所以我在寻找多版本管理工具。 [En] It’s too troubl…

    Go语言 2023年5月25日
    055
  • Context包源码解析(附面经)

    Context就相当于一个树状结构最后请回答一下这个问题:context包中的方法是线程安全吗? Context包中主要有一个接口和三个结构体 type Context inter…

    Go语言 2023年5月25日
    058
  • 许式伟:Go+ 演进之路

    7 月 10 日,一年一度的 ECUG Con 2022 在线上圆满举行。许式伟作为七牛云 CEO、ECUG 社区发起人、Go+ 语言发明人,为大家来带了《Go+ 演进之路》的主题…

    Go语言 2023年5月25日
    080
  • Go语言之函数

    函数就是一块执行特定任务的代码,在输入源的基础上通过一些算法生成预期的输出。 Go 语言中的函数声明语法如下: func 函数名(参数名 类型,参数名 类型)(返回值1类型,返回值…

    Go语言 2023年5月25日
    034
  • 第十五章:指针类型

    本篇翻译自《Practical Go Lessons》 Chapter 15: Pointer type 1 你将在本章将学到什么? 什么是指针? 什么时指针类型? 如何去创建并使…

    Go语言 2023年5月25日
    054
  • Go微服务框架go-kratos学习05:分布式链路追踪 OpenTelemetry 使用

    一、分布式链路追踪发展简介 1.1 分布式链路追踪介绍 关于分布式链路追踪的介绍,可以查看我前面的文章 微服务架构学习与思考(09):分布式链路追踪系统-dapper论文学习(ht…

    Go语言 2023年5月25日
    045
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球