在不同的goroutine中进行读写操作时,我是否必须同步它们?

huangapple go评论116阅读模式
英文:

Must I synchronise read and write operations when doing it from different goroutines?

问题

据我所知,每个对服务器的请求都会创建一个新的goroutine。例如(可能是不正确的代码,但这个主题不是关于它的):

  1. package main
  2. import "net/http"
  3. var exampleMap map[string]string
  4. func handlerPost(w http.ResponseWriter, r *http.Request) {
  5. switch r.Method {
  6. case "POST":
  7. {
  8. exampleMap["test"] = test // 我需要同步这个写操作吗?
  9. }
  10. case "GET":
  11. {
  12. if v, ok := exampleMap["test"]; ok { // 那么读操作呢?
  13. fmt.Println(v)
  14. }
  15. }
  16. }
  17. }
  18. func main() {
  19. http.HandleFunc("/", handlerPost)
  20. http.ListenAndServe(":8080", nil)
  21. }

这是否意味着像这样做是不安全的,我必须使用sync.Map(例如),如果这里的map是数据库查询呢?在这种情况下我该怎么办?谢谢!

英文:

As I know, every requests to the server creates new goroutine. For ex (probably incorrect code, but this topic is not about it):

package main

  1. import "net/http"
  2. var exampleMap map[string]string
  3. func handlerPost(w http.ResponseWriter, r *http.Request) {
  4. switch r.Method {
  5. case "POST":
  6. {
  7. exampleMap["test"] = test // Must I syncrhonise this writing?
  8. }
  9. case "GET":
  10. {
  11. if v, ok := exampleMap["test"] { // And what about reading?
  12. fmt.Println(v)
  13. }
  14. }
  15. }
  16. }
  17. func main() {
  18. http.HandleFunc("/", handlerPost)
  19. http.ListenAndServe(":8080", nil)
  20. }

Does it mean that its unsafe to do it like this and I have to use sync.Map (for example), and what about if instead map here was a database queries? What can I do in this case. Thank you!

答案1

得分: 2

exampleMap在多个goroutine之间共享,因此需要对其进行同步访问。可以使用互斥锁(mutex),或者使用读写锁(RWMutex)以提高性能:

  1. var exampleMap map[string]string
  2. var exampleMutex sync.RWMutex
  3. ...
  4. exampleMutex.Lock()
  5. exampleMap["test"] = test
  6. exampleMutex.Unlock()
  7. ...
  8. exampleMutex.RLock()
  9. v, ok := exampleMap["test"]
  10. exampleMutex.RUnlock()
  11. if ok {
  12. ...
  13. }

请注意,以上代码是用于同步访问exampleMap的示例。

英文:

exampleMap is shared among goroutines, so you have to synchronize access to it. A mutex would do, a RWMutex would perform better:

  1. var exampleMap map[string]string
  2. var exampleMutex sync.RWMutex
  3. ...
  4. exampleMutex.Lock()
  5. exampleMap["test"] = test
  6. exampleMutex.Unlock()
  7. ...
  8. exampleMutex.RLock()
  9. v, ok := exampleMap["test"]
  10. exampleMutex.RUnlock()
  11. if ok {
  12. ...
  13. }
  14. </details>

huangapple
  • 本文由 发表于 2022年9月5日 23:18:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/73611552.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定