为了账号安全,请及时绑定邮箱和手机立即绑定

Golang Goroutine 与 channel 同步

Golang Goroutine 与 channel 同步

Go
慕虎7371278 2022-05-23 15:11:20
我有以下程序,其中使用 gorilla mux 创建 HTTP 服务器。当任何请求到来时,它启动 goroutine 1。在处理中,我正在启动另一个 goroutine 2。我想在 goroutine 1 中等待 goroutine 2 的响应?我怎么能这样做?如何确保只有 goroutine 2 会响应 goroutine 1?GR3 可以创建 GR4,GR 3 应该只等待 GR4。GR = Goroutine服务器    package mainimport (    "encoding/json"    "fmt"    "net/http"    "strconv"    "time"    "github.com/gorilla/mux")type Post struct {    ID    string `json:"id"`    Title string `json:"title"`    Body  string `json:"body"`}var posts []Postvar i = 0func getPosts(w http.ResponseWriter, r *http.Request) {    w.Header().Set("Content-Type", "application/json")    i++    fmt.Println(i)    ch := make(chan int)    go getTitle(ch, i)    p := Post{        ID: "123",    }    // Wait for getTitle result and update variable P with title    s := <-ch    //    p.Title = strconv.Itoa(s) + strconv.Itoa(i)    json.NewEncoder(w).Encode(p)}func main() {    router := mux.NewRouter()    posts = append(posts, Post{ID: "1", Title: "My first post", Body: "This is the content of my first post"})    router.HandleFunc("/posts", getPosts).Methods("GET")    http.ListenAndServe(":9999", router)}func getTitle(resultCh chan int, m int) {    time.Sleep(2 * time.Second)    resultCh <- m}
查看完整描述

2 回答

?
德玛西亚99

TA贡献1770条经验 获得超3个赞

有几种方法可以做到这一点,一个简单的方法是使用渠道


将 getTitle 函数更改为此


func getTitle(resultCh chan string)  {

   time.Sleep(2 * time.Second)

   resultCh <- "Game Of Thrones"

}

getPosts 会像这样使用它


func getPosts(w http.ResponseWriter, r *http.Request) {

   w.Header().Set("Content-Type", "application/json")


   ch := make(chan string)

   go getTitle(ch)



   s := <-ch // this will wait until getTile inserts data to channel 

   p := Post{

       ID: s,

   }


   json.NewEncoder(w).Encode(p)

}

我怀疑你是新来的,这是一个基本的频道用法,在这里查看更多详细信息频道


查看完整回答
反对 回复 2022-05-23
?
繁星淼淼

TA贡献1775条经验 获得超11个赞

所以你遇到的问题是你还没有真正了解如何处理并发代码(不是dis,我曾经在那里)。其中大部分都不是围绕渠道进行的。正如@kojan 的回答所解释的那样,这些频道工作正常。出问题的地方在于i变量。首先,您必须了解这i不是原子突变,因此如果您的客户端请求并行到达,您可能会弄乱数字:


C1 :          C2:

i == 6        i == 6

i++           i++

i == 7        i == 7

软件中的两个增量实际上变成了一个增量,因为实际上i++是 3 个操作:加载、增量、存储。


你遇到的第二个问题是它i不是一个指针,所以当你传递i给你的 go 例程时,你正在制作一个副本。go 例程中的i被发送回通道,并成为连接字符串中的第一个数字,您可以观看增量。然而i,在字符串尾部使用的剩余部分继续通过连续的客户端调用增加。


查看完整回答
反对 回复 2022-05-23
  • 2 回答
  • 0 关注
  • 122 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信