Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Golang Goroutine与信道同步_Go - Fatal编程技术网

Golang Goroutine与信道同步

Golang Goroutine与信道同步,go,Go,我有以下程序,其中HTTP服务器是使用gorilla mux创建的。 当任何请求出现时,它将启动goroutine1。在处理过程中,我正在启动另一个goroutine2。 我想等待goroutine2在goroutine1中的响应?我怎么能做到? 如何确保只有goroutine2会对goroutine1做出响应 GR3可以创建GR4,GR3应该只等待GR4 GR=Goroutine 服务器 package main import ( "encoding/json" "

我有以下程序,其中HTTP服务器是使用gorilla mux创建的。 当任何请求出现时,它将启动goroutine1。在处理过程中,我正在启动另一个goroutine2。 我想等待goroutine2在goroutine1中的响应?我怎么能做到? 如何确保只有goroutine2会对goroutine1做出响应

GR3可以创建GR4,GR3应该只等待GR4

GR=Goroutine

服务器

    package main

import (
    "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 []Post

var i = 0

func 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
}
预期结果

 {"id":"123","title":"112112","body":""}
 {"id":"123","title":"113113","body":""}
 {"id":"123","title":"115115","body":""}
 {"id":"123","title":"116116","body":""}
 {"id":"123","title":"117117","body":""}

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

将getTitle函数更改为

func getTitle(resultCh chan string)  {
   time.Sleep(2 * time.Second)
   resultCh <- "Game Of Thrones"
}
func getTitle(结果字符串){
时间。睡眠(2*时间。秒)

resultCh因此,您面临的问题是,您没有真正学会如何处理并发代码(不是dis,我曾经在那里)。其中大部分并非围绕频道。正如@kojan的回答所解释的,频道工作正常。出现问题的地方在于
i
变量。首先,您必须了解
i
并没有被原子化地变异,因此,如果您的客户端请求同时到达,您可能会弄乱数字:

C1 :          C2:
i == 6        i == 6
i++           i++
i == 7        i == 7
软件中的两个增量实际上变成了一个增量,因为
i++
实际上是三个操作:加载、增量、存储


第二个问题是,
i
不是指针,因此当您将
i
传递到go例程时,您正在制作一个副本。go例程中的
i
将被发送回频道,并成为您可以观察增量的串联字符串中的第一个数字。但是,
i
被保留下来,这是使用的字符串尾部的d随着连续的客户端调用而不断增加。

谢谢Kojan,我创建了通道,但结果不同步。有一段时间我在GR1中得到了GR4结果。您可以检查服务器和客户端代码。我更新了问题服务器代码看起来正确(而客户端代码是不相关的)你可以看到预期的结果与实际情况如果你一个接一个地激发curl,那么它就工作了,但是当使用客户机激发多个请求时,它就失败了这不正确max,当我被传递到GR2时,我们对get函数进行了另一次调用,这做了另一次i++所以当GR2完成时,我现在是2,而不是像我们传递给它的1。这是因为您的i是globalThanks,而不是变量i,我使用了newvalue:=rand.Intn(100),go-getTitle(ch,newvalue)…现在一切正常
func getTitle(resultCh chan string)  {
   time.Sleep(2 * time.Second)
   resultCh <- "Game Of Thrones"
}
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)
}
C1 :          C2:
i == 6        i == 6
i++           i++
i == 7        i == 7