go 進程 線程 協程 併發

package main

import (
   "fmt"
   //"runtime"
   "sync"
   "time"
)

//go併發
// 進程 線程
// 進程是程序在操作系統中的一次執行過程 系統進行資源分配 和調度的一個獨立單位
// 線程是進程的一個執行實體 是CPU調度和分派的基本單位 他是比進程更小的能獨立運行的基本單位
// 一個進程可以創建和撤銷多個線程 同一個進程中的多個線程之間可以併發執行

//併發 並行
//多線程程序在單核心的cpu上運行 稱爲併發
//多線程程序在多核心的cpu上運行 稱爲並行
//併發與並行並不相同 併發主要是由切換時間片來實現 同時 運行
//並行是直接利用多核實現多線程的運行 Go程序可以設置使用核心數,以發揮多核計算機的能力

//協程 線程
//協程 獨立的棧空間 共享堆空間 調度是由用戶自己控制的 本質上有點類似於用戶級線程,這些用戶級線程的調度也是自己實現的
//線程 一個線程上可以跑多個協程 協程是輕量級的線程

// Goroutine 介紹
//goroutine 是一種非常輕量級的實現,可在單個進程裏執行成千上萬的併發任務,它是Go語言併發設計的核心。

//說到底 goroutine 其實就是線程,但是它比線程更小,十幾個 goroutine 可能體現在底層就是五六個線程,而且Go語言內部也實現了 goroutine 之間的內存共享。

//使用 go 關鍵字就可以創建 goroutine,將 go 聲明放到一個需調用的函數之前,在相同地址空間調用運行這個函數,這樣該函數執行時便會作爲一個獨立的併發線程,這種線程在Go語言中則被稱爲 goroutine。

//go 關鍵字放在方法調用前新建一個 goroutine 並執行方法體
//go GetThingDone(param1, param2)
//
//go func(param1, param2) {
//}(val1, val2)
//
//
////直接新建一個 goroutine 並在 goroutine 中執行代碼塊
//go {
////do someting...
//}

//使用普通函數來創建go 併發
//使用 go 關鍵字創建 goroutine 時,被調用函數的返回值會被忽略。
//如果需要在 goroutine 中返回數據,請使用後面介紹的通道(channel)特性,通過通道把數據從 goroutine 中作爲返回值傳出。

func running() {
   var times int
   // 構建一個無限循環
   for {
      times++
      fmt.Println("tick", times)
      // 延時1秒
      time.Sleep(time.Second)
   }
}

//Go語言併發通信
var counter int = 0

func Count(lock *sync.Mutex) {
   lock.Lock()
   counter++
   fmt.Println(counter)
   lock.Unlock()
}
func printer(c chan int) {
   // 開始無限循環等待數據
   for {
      // 從channel中獲取一個數據
      data := <-c
      // 將0視爲數據結束
      if data == 0 {
         break
      }
      // 打印數據
      fmt.Println(data)
   }
   // 通知main已經結束循環(我搞定了!)
   c <- 0
}

func main() {
   // 併發執行程序
   //go running()
   //// 接受命令行輸入, 不做任何事情
   //var input string
   //fmt.Scanln(&input)

   //lock := &sync.Mutex{}
   //for i := 0; i < 1000000; i++ {
   // go Count(lock)
   //}
   //for {
   // lock.Lock()
   // c := counter
   // lock.Unlock()
   // runtime.Gosched()
   // if c >= 10 {
   //    break
   // }
   //}

   // 創建一個channel
   c := make(chan int)
   // 併發執行printer, 傳入channel
   go printer(c)
   for i := 1; i <= 10; i++ {
      // 將數據通過channel投送給printer
      c <- i
   }
   // 通知併發的printer結束循環(沒數據啦!)
   c <- 0
   // 等待printer結束(搞定喊我!)
   <-c
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章