golang 中的互斥鎖和管道

package main
import (
   "fmt"
   "sync"
   "time"
)
// 需求:現在要計算 1-200 的各個數的階乘,並且把各個數的階乘放入到map中。
// 最後顯示出來。要求使用goroutine完成
// 思路
// 1. 編寫一個函數,來計算各個數的階乘,並放入到 map中.
// 2. 我們啓動的協程多個,統計的將結果放入到 map中
// 3. map 應該做出一個全局的.
var (
   myMap = make(map[int]int, 10)
   //聲明一個全局的互斥鎖
   //lock 是一個全局的互斥鎖,
   //sync 是包: synchornized 同步
   //Mutex : 是互斥
   lock sync.Mutex
)
// test 函數就是計算 n!, 讓將這個結果放入到 myMap
func test(n int) {
   res := 1
   for i := 1; i <= n; i++ {
      res *= i
   }
   //這裏我們將 res 放入到myMap
   //加鎖
   lock.Lock()
   myMap[n] = res 
   //解鎖
   lock.Unlock()
}
func main() {
   // 我們這裏開啓多個協程完成這個任務[20個]
   for i := 1; i <= 20; i++ {
      go test(i)
   }
   //休眠10秒鐘【第二個問題 】
   time.Sleep(time.Second * 5)
   //這裏我們輸出結果,變量這個結果
   lock.Lock()
   for i, v := range myMap {
      fmt.Printf("map[%d]=%d\n", i, v)
   }
   lock.Unlock()
}
type Cat struct {
   Name string
   Age  int
}
func main() {
   //定義一個存放任意數據類型的管道 3個數據
   var allChan chan interface{}
   allChan = make(chan interface{}, 3)
   // 向管道中放入數據
   allChan <- 10
   allChan <- "tom jack"
   cat := Cat{"小花貓", 4}
   allChan <- cat
   //從管道中獲取數據
   <-allChan
   <-allChan
   newCat := <-allChan //從管道中取出的Cat是什麼?
   fmt.Printf("newCat=%T , newCat=%v\n", newCat, newCat)
   //使用類型斷言,將interface{}類型轉爲Cat類型
   a := newCat.(Cat)
   fmt.Printf("newCat., a.Name)
}
func main() {
   intChan := make(chan int, 3)
   intChan <- 100
   intChan <- 200
   close(intChan) // close
   //這是不能夠再寫入數到channel
   //intChan<- 300
   fmt.Println("okook~")
   //當管道關閉後,讀取數據是可以的
   n1 := <-intChan
   fmt.Println("n1=", n1)
   //遍歷管道
   intChan2 := make(chan int, 100)
   for i := 0; i < 100; i++ {
      intChan2 <- i * 2 //放入100個數據到管道
   }
   //在遍歷時,如果channel沒有關閉,則會出現deadlock的錯誤
   //在遍歷時,如果channel已經關閉,則會正常遍歷數據,遍歷完後,就會退出遍歷
   close(intChan2)
   for v := range intChan2 {
      fmt.Println("v=", v)
   }
}

//write Data
func writeData(intChan chan int) {
   for i := 1; i <= 50; i++ {
      //放入數據
      intChan <- i //
      fmt.Println("writeData ", i)
   }
   close(intChan) //關閉
}
//read data
func readData(intChan chan int, exitChan chan bool) {
   for {
      v, ok := <-intChan
      if !ok {
         break
      }
      time.Sleep(time.Second)
      fmt.Printf("readData 讀到數據=%v\n", v)
   }
   exitChan <- true
   close(exitChan)
}
func main() {
   //創建兩個管道
   intChan := make(chan int, 10)
   exitChan := make(chan bool, 1)
   go writeData(intChan)
   go readData(intChan, exitChan)
   for {
      _, ok := <-exitChan
      if !ok {
         break
      }
   }
}
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/5_O6jmudmMAGe2810jy5mg