golang 協程通道,map,redis的併發性

2022-08-10 03:00:09 字數 1579 閱讀 1712

假如我們沒有用協程通道或者加鎖的方式,直接併發使用map,會出現線性不安全

例如:

package main

import (

"time"

"fmt"

)var tmap map[int]int

func main()

time.sleep(1e10)

fmt.println("--------------map = ", len(tmap))

}func putmap(i int)

報錯:

解決方法:

使用鎖之後就不會有問題:

package main

import (

"time"

"fmt"

"sync"

)var tmap map[int]int

var mutex sync.mutex

func main()

time.sleep(1e10)

fmt.println("--------------map = ", len(tmap))

}func putmap(i int)

又或者是利用協程通道,來保證執行緒安全

package main

import (

"time"

"fmt"

)var tmap map[int]int

func main()

time.sleep(1e10)

fmt.println("--------------map = ", len(tmap))

}func putmap(data chan int, i int)

func goroutine(data chan int)

}

go的哲學之一就是:不要通過共享記憶體來通訊,而要通過通訊來共享記憶體,前者就是傳統的加鎖,後者就是channel。反正涉及到併發安全性的資料結構,盡量使用協程通道:傳送乙個資料到channel 和 從channel接收乙個資料 都是 原子性的。

可以認為加鎖的map就是erlang裡面的ets,而使用協程通道就是erlang裡面的程序裡的資料結構

最後我們來看一下go對redis的併發操作:

package main

import (

"time"

"slg_game_server/server/goredis"

"slg_game_server/server/util"

)func main()

time.sleep(1e10)

}func putredis(i int)

也沒任何問題!!!

因為redis服務端是個單執行緒的架構,不同的client雖然看似可以同時保持連線,但發出去的命令在伺服器看來是序列化執行的,

因此對服務端來說,並不存在併發問題!!!

Golang協程與通道整理

協程goroutine 不由os排程,而是使用者層自行釋放cpu,從而在執行體之間切換。go在底層進行協助實現 涉及系統呼叫的地方由go標準庫協助釋放cpu 總之,不通過os進行切換,自行切換,系統執行開支大大降低 通道channel 併發程式設計的關鍵在於執行體之間的通訊,go通過通過channe...

Golang協程與通道整理

協程goroutine 不由os排程,而是使用者層自行釋放cpu,從而在執行體之間切換。go在底層進行協助實現 涉及系統呼叫的地方由go標準庫協助釋放cpu 總之,不通過os進行切換,自行切換,系統執行開支大大降低 通道channel 併發程式設計的關鍵在於執行體之間的通訊,go通過通過channe...

Go 協程 通道

目錄 go 協程 go 通道 go 協程go 協程可以看作是輕量級執行緒。與執行緒相比,建立乙個go協程的成本很小。因此在go應用中,常常會看到有數以千計的go協程併發地執行 go 協程相比於執行緒的優勢 啟動乙個go協程 在呼叫函式和方法時,在前面加上關鍵字go,可以讓乙個新的go協程併發執行 p...