go併發程式設計筆記

weixin_33924312發表於2019-01-07

併發程式設計

  • 一、併發程式設計的相關概念
    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
}

二、常見的併發模式

相關文章