zoukankan      html  css  js  c++  java
  • 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()
  • 相关阅读:
    POJ 2155 Matrix
    Codeforces 626D Jerry's Protest 「数学组合」「数学概率」
    Codeforces 626E Simple Skewness 「数学」「二分」
    Codeforces 633D
    Codeforces 631C
    二分查找
    CodeForces 617C【序枚举】
    HDU 4405 【概率dp】
    ZOJ 3329 【概率DP】
    POJ 2096 【期望DP】
  • 原文地址:https://www.cnblogs.com/liuqun/p/12655167.html
Copyright © 2011-2022 走看看