美文网首页
go并发编程笔记

go并发编程笔记

作者: yongfutian | 来源:发表于2019-01-07 11:52 被阅读0次

    并发编程

    • 一、并发编程的相关概念
      1、并发编程概念:使多个任务【程序】可以在同一时间执行以便能够更快的得到结果
      2、多元程序:允许操作系统同时运行多个程序,cpu来回切换,缺点:对系统资源进行无限制的抢夺造成程序频繁发生死锁现象
      3、串行程序:只能被顺序执行的指令列表
      4、并行程序:可以在并行的硬件上执行的并发程序
      5、并发程序:被并发的执行的两个或两个以上的串行程序的统称
      6、并发系统
      7、并发程序的不确定性:没有明确的执行顺序
      8、并发程序的内部交互
          同步的原则:某个资源同一时刻只能被一个程序占用
          同步的作用:避免在并发访问共享资源时可能存在的冲突,以及确保在互相传递数据时能够顺利的接通

    • 二、多进程编程
      1、IPC:多进程程序中,程序之间需要互相协作完成任务,而多个进程程序之间的通讯方式就叫做IPC
         基于通讯的IPC方法:
           以数据传输为手段:
             管道:被用来传送字节流
             消息队列:被用来传送结构化的消息对象
           以共享内存为手段:主要为共享内存区,是最快的一种IPC方法
         基于信号的IPC方法:操作系统信号机制,是唯一的一种一部IPC方法
         基于同步的IPC方法:操作系统信号灯
         
         注:golang支持的 管道、信号、socket
      2、进程:程序的执行被称为一个进程,是操作系统进行资源分配的一个基本单位
        a、进程的衍生:fork子进程
        b、进程的标识:pid、ppid
        c、进程的状态:
          可运行状态R:如果一个进程处于该状态,那么说明它将要、立刻或正在CPU上运行
          可中断的睡眠状态S:当系统正在等待某个事件【如网络连接或信号灯】的发生时会进入此状态
          不可中断的睡眠状态D:和S的唯一区别就是不可被打断的
          暂停状态或跟踪状态T:向进程发送SIGSTOP信号就会使该进程进入暂停状态
          僵死状态Z:表示改进程即将要结束,进程占用的绝大多数资源会也都已经回收
          退出状态X:
        d、进程的空间:
          用户空间:用户进程不能与计算机硬件进行交互,生存与用户空间
          内核空间:内核可以与硬件进行交互,生存于内核空间
        e、系统调用:为了使用户进程能够使用操作系统更底层的功能,内核暴露一些接口供其调用,这些接口调用称之为系统调用
          内核态:系统调用时,CPU切换到内核态
          用户态:大部分时间cup处于用户态
          CPU切换
        f、进程切换和进程调度:是程序并发执行的基础

    3、同步
        竞态条件:当几个进程同时对同一个资源进行访问的时候,就很可能造成互相的干扰,这种互相的干扰就被称为竞态条件;通常在编码和测试过程中难以察觉
        原子操作:执行过程中不能被中断的操作
          必须有一个单一的汇编指令代表,并且需要得到芯片级别的支持;内核只提供了二进制位和整数的原子操作,只适合细粒度的简单操作, sync/atomic
        临界区即互斥:只能被串行化的访问或执行的某个资源或某段代码
          排他原则,不能依赖于任何计算机硬件
          
    三、管道

    go语言高级编程笔记

    一、面向并发的编程模型
      首先,我们使用sync.WaitGroup来等待一组线程的结束,在主线程里可以调用Wait方法阻塞至所有线程结束;父线程调用Add方法来设定应等待的线程的数量;每个被等待的线程在结束时应调用Done方法,释放等待的线程的数量
      在worker的循环中,为了保证total.value += i的原子性,我们通过sync.Mutex加锁和解锁来保证该语句在同一时刻只被一个线程访问

    package main
    
    import (
        "fmt"
        "sync"
    )
    
    var total struct {
        sync.Mutex
        value int
    }
    
    func worker(wg *sync.WaitGroup){
        defer wg.Done()
        
        for i := 0; i<=100; i++ {
            //total.Lock()
            total.value += i
            //total.Unlock()
        }
    }
    
    func main(){
        var wg sync.WaitGroup
        wg.Add(2)
        go worker(&wg)
        go worker(&wg)
        wg.Wait()
    
        fmt.Println(total.value)
    }
    

    使用标准库的sync/atomic包对原子操作的支持进行改进

    package main
    
    import (
        "fmt"
        "sync"
        "sync/atomic"
    )
    
    var total uint64
    
    func worker(wg *sync.WaitGroup){
        defer wg.Done()
    
        var i uint64
        for i = 0; i<=100; i++ {
            atomic.AddUint64(&total, i)
        }
    }
    
    func main(){
        var wg sync.WaitGroup
        wg.Add(2)
        go worker(&wg)
        go worker(&wg)
        wg.Wait()
    
        fmt.Println(total)
    }
    

    单件模式

    var (
        instance *singleton
        once     sync.Once
    )
    
    func Instance() *singleton {
        once.Do(func() {
        instance = &singleton{}
        })
        return instance
    }
    

    二、常见的并发模式

    相关文章

      网友评论

          本文标题:go并发编程笔记

          本文链接:https://www.haomeiwen.com/subject/ixxurqtx.html