go协程 && channel

goroutine(协程)&& channel(管道)
使用并发或者并行的方式,CPU
线程和进程说明

  1. 进程就是程序在操作系统中的一次执行过程中,是系统进行资源分配和调度的基本单位。
  2. 线程是进程的一个执行实例,是程序执行的最小单元,它是比进程更小的能独立运行的基本单位。
  3. 一个进程可以创建和销毁多个线程,同一个进程中的多个线程可以并发执行
  4. 一个程序至少有一个进程,一个进程至少有一个线程

并发和并行的区别

  1. 1)多线程程序在单核上运行,就是并发
    1. 多线程在多核上运行,就是并行

go的协程和go的主线程

  1. 1)go主线程(有程序员直接称为线程/也可以理解成进程):一个go线程上,可以起多个协程。 可以这样理解,协程是轻量级的线程
  2. 2)go协程的特点
    2.1. 有独立的栈空间
    2.2. 共享程序堆空间
    2.3. 调度由用户控制
    2.4. 协程是轻量级的线程

goroutine

  1. 主线程是一个物理线程,直接作用在cpu上,是重量级的,非常耗费CPU资源。
  2. 协程从主线程开启的,是轻量级的线程,是逻辑态。对资源消耗相对小。
  3. golang的协程机制是重要的特点,可以轻松的开启上万个协程,其他编程语言的开发机制是一般基于线程的,开启过多的线程,
    资源耗费大,这里就凸显golang在并发上的优势了。

为什么需要channel

  1. 主线程在等待所有goroutine全部完成的时间很难完成,我们这里设置10秒,仅仅是估算。
  2. 如果主线程休眠时间长了,会加长等待时间,如果等待时间短了,可能还有goroutine处于工作状态,这时也会随主线程的退出而销毁
  3. 通过全局变量加锁同步来实现通讯,也不利用多个协程对全局变量的读写操作,
  4. 上面种种分析都在呼唤一个新的通讯机制 channel

channel介绍

  1. channel本质就是一个数据结构-队列
  2. 数据是先进先出
  3. 线程安全,多goroutine访问时,不需要加锁,就是说channel本身就是线程安全的。
  4. channel时有类型的,一个string的channel只能存放string类型的数据。

channel 管道-基本使用
var 变量名 chan 数据类型

说明

  1. channel是引用类型
  2. channel必须初始化才能写入数据,即make后才能使用
  3. 管道是有类型的,intChan只能写入数据int

channel 管道注意事项

  1. channel中只能存放指定的数据类型
  2. channel的数据放满后,就不能再放入了
  3. 如果从channel取出数据后,可以继续放入
  4. 在没有使用协程的情况下,如果channel数据取完了,再取就会报dead lock

channel 的遍历和关闭
使用内置函数close可以关闭channel,当channel关闭后,就不能再向channel写数据了,但是仍然可以从该channel读取数据

channel的遍历
channel支持for-range的方式进行遍历,遍历细节

  1. 1)在遍历时,如果channel没有关闭,则会出现deadlock的错误

    1. 在遍历是,如果channel已经关闭,则会正常遍历数据,遍历完后,就会退出遍历。
  2. 默认情况下,管道是双向的。

  3. 声明为只写 , 声明为只读

  4. 使用select可以解决从管道取数据的阻塞问题。

  5. goroutine中使用recover,解决协程中出现panic,导致程序崩溃问题。

反射 tag 解决序列化key的名字
基本介绍
7. 反射可以在运行时动态获取变量的各种信息,比如变量的类型type,类别
8. 如果是结构体变量,还可以获取到结构体本身的信息(包括结构体的字段,方法)
9. 通过反射,可以修改变量的值,可以调用关联的方法
10. 使用反射,需要import (“reflect")
11. 变量、interface{}、和reflect.Value是可以相互转换的。


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  1. 常量使用const修改

  2. 常量在定义的时候,必须初始化

  3. 常量不能修改

  4. 常量只能修饰bool、数值类型(int、float系列)、string类型

  5. 语法 const identifier [type] = value
    举栗子: const name = “tome”
    const tax float64 = 0.8

  6. go 中没有常量名必须字母大写的规范

  7. 仍然通过首字母的大小写来控制常量的访问范围。

反射的注意事项和细节

  1. reflect value kind 获取变量的类别,返回的是一个常量
  2. Type和kind的区别 :type是类型,kind是类别,type和kind可能相同,也可能是不相同的
  3. 通过反射可以让变量在interface和refleact.value之间相互转换,
  4. 使用反射的方式获取变量的值(并返回对应的值)要求数据类型匹配,比如x是int,name就应该使用reflect.Value(x).int 而不能使用其它的,否则报panic
  5. 通过反射的修改变量,注意当使用setxx方法来设置需要通过对应的指针类型来完成,这样才能改变传入的变量的值,同时需要使用到reflect.Value.Elem()的方法。
  6. reflect.Value.Elem()
posted @ 2019-07-23 20:56  liulonglong  阅读(317)  评论(0编辑  收藏  举报