• # Go学习-Day8


    Go学习-Day8

    单元测试

    • testing框架会将xxx_test.go的文件引入,调用所有TestXxx的函数

    • 在cal_test.go文件里面写这个

    • package main
      
      import "testing"
      
      func TestAdd(t *testing.T) {
      	a, b := 1, 2
      	if add(a, b) != 4 {
      		t.Fatalf("Wrong Answer!")
      	}
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    • cal.go文件里写这个

    • package main
      
      func add(a int, b int) int {
      	return a + b
      }
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    • 运行go test -v的命令,就能运行单测

    • 可以得到结果

    • === RUN   TestAdd
          cal_test.go:8: Wrong Answer!
      --- FAIL: TestAdd (0.00s)
      
      
      • 1
      • 2
      • 3
      • 4
    • testing框架import这个test文件之后,会调用所有TestXxx的函数,注意大写!

    Goroutine

    进程和线程

    • 进程是程序的在操作系统的一次执行过程
    • 线程是比进程更小的单位,一个进程能创建销毁多个线程
    • 一个程序至少有一个进程,一个进程至少有一个线程

    并发和并行

    • 多线程在单核上运行,就是并发
    • 多线程在多核上运行,就是并行

    Go协程和主线程

    • 主线程类似进程

    • 协程类似线程,是轻量级的线程

    • 协程的特点

      • 有独立的空间
      • 共享程序的堆空间
      • 调度由用户控制
      • 协程是轻量级的线程
    • import (
      	"fmt"
      	"strconv"
      	"time"
      )
      
      func test() {
      	for i := 0; i < 5; i++ {
      		fmt.Println("test() calls! " + strconv.Itoa(i))
      		time.Sleep(time.Second)
      	}
      }
      
      func main() {
      	go test()
      
      	for i := 0; i < 5; i++ {
      		fmt.Println("main() calls! " + strconv.Itoa(i))
      		time.Sleep(time.Second)
      	}
      }
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
    • 输出

    • main() calls! 0
      test() calls! 0
      test() calls! 1
      main() calls! 1
      main() calls! 2
      test() calls! 2
      test() calls! 3
      main() calls! 3
      main() calls! 4
      test() calls! 4
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • go关键字会另起一个协程,主线程执行到这里会开一个协程并行执行,如果主线程执行完毕退出,协程会被强制退出

    MPG模式

    • M(Machine)是操作系统的主线程,也就是物理线程

    • P(Processor)协程执行的上下文

    • G(Gorountine)协程

    • Go语言的协程是轻量级的,是逻辑态的,可以起上万个协程;而C/java的多线程是内核态的,几千个就会耗光CPU

    CPU相关

    runtime.NumCPU()
    //获取本地CPU数目
    runtime.GOMAXPROCS(int)
    //设置GO最大可用的CPU数目
    //Go Max Processors
    
    • 1
    • 2
    • 3
    • 4
    • 5

    协程并行的资源竞争

    • 多个协程同时访问一个资源会发生冲突,会发生并发问题

    • 在java中我们有锁和原子类来保证并发安全

    • 声明一个全局锁变量lock

    • lock sync.Mutex
      //sync是同步的意思,Muti-excluded互斥锁?
      
      • 1
      • 2
    • lock.Lock()//在进行并发的读写操作的时候,先上个锁
      ...//在进行操作的时候,别的协程会排队等待
      lock.Unlock()//解锁之后,才能给别的协程使用
      
      • 1
      • 2
      • 3
    • 主线程读的时候也需要加锁,因为底层不知道协程已经解锁了,会发生资源冲突

    • 但是这样不同协程之间没办法通讯,不知道什么时候协成完成任务了,白白空转浪费时间,或者提前结束主线程,终止协程,管道可能能解决这些问题,明天再学

  • 相关阅读:
    【小白专用】安装Apache2.4+ 安装PHP8.2+ php与sql server 2008 r2连接测试教程
    PKG打包sqlite3项目,如何添加node_sqlite3.node依赖
    机器学习10—多元线性回归模型
    web 安全总结
    电商平台API接口大全(商品详情 API 返回值说明)
    SVG 绘制微信订阅号icon
    799. 香槟塔 : 简单线性 DP 运用题
    JavaEE进阶教程系列文章目录汇总
    MySQL环境变量配置的教程
    第150篇 笔记-元宇宙(Metaverse)
  • 原文地址:https://blog.csdn.net/gfyy_bkj/article/details/132528675