Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/8.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
带着奇怪的结果去goroutine_Go_Goroutine - Fatal编程技术网

带着奇怪的结果去goroutine

带着奇怪的结果去goroutine,go,goroutine,Go,Goroutine,当我运行goroutines时,我通常得到40作为值,我知道这是关于并发性的,但是为什么最后一个数字会出现呢?我想输出必须是: Page number: 34 Page number: 12 Page number: 8 Page number: 2 Page number: 29 示例源代码: package main import ( "fmt" "io/ioutil" "net/http" ) func getWebPageConte

当我运行goroutines时,我通常得到40作为值,我知道这是关于并发性的,但是为什么最后一个数字会出现呢?我想输出必须是:

Page number:  34  
Page number:  12  
Page number:  8  
Page number:  2  
Page number:  29
示例源代码

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
)

func getWebPageContent(url string, c chan int, val int) interface{} {

    if r, err := http.Get(url); err == nil {
        defer r.Body.Close()
        if body, err := ioutil.ReadAll(r.Body); err == nil {
            c <- val
            return string(body)
        }
    } else {
        fmt.Println(err)
    }
    return "XoX"

}

const MAX_TH = 40

func main() {

    // pln := fmt.Println
    messages := make(chan int)
    for j := 0; j < MAX_TH; j++ {
        go func() { getWebPageContent("http://www.example.com", messages, j) }()
    }

    routine_count := 0
    var page_number int
    for {
        page_number = <-messages
        routine_count++
        fmt.Println("Page number: ", page_number)
        if routine_count == MAX_TH {
            break
        }
    }
    close(messages)
}
主程序包
进口(
“fmt”
“io/ioutil”
“net/http”
)
func getWebPageContent(url字符串、c chan int、val int)接口{}{
如果r,err:=http.Get(url);err==nil{
延迟r.Body.Close()
if body,err:=ioutil.ReadAll(r.body);err==nil{
C
围棋编程语言

在并发使用闭包时可能会出现一些混乱。 考虑下面的程序:

func main() {
    done := make(chan bool)

    values := []string{"a", "b", "c"}
    for _, v := range values {
        go func() {
            fmt.Println(v)
            done <- true
        }()
    }

    // wait for all goroutines to complete before exiting
    for _ = range values {
        <-done
    }
}
比如说,

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
)

func getWebPageContent(url string, c chan int, val int) interface{} {
    if r, err := http.Get(url); err == nil {
        defer r.Body.Close()
        if body, err := ioutil.ReadAll(r.Body); err == nil {
            c <- val
            return string(body)
        }
    } else {
        fmt.Println(err)
    }
    return "XoX"
}

const MAX_TH = 40

func main() {

    // pln := fmt.Println
    messages := make(chan int)
    for j := 0; j < MAX_TH; j++ {
        j := j
        go func() { getWebPageContent("http://www.example.com", messages, j) }()
    }

    routine_count := 0
    var page_number int
    for {
        page_number = <-messages
        routine_count++
        fmt.Println("Page number: ", page_number)
        if routine_count == MAX_TH {
            break
        }
    }
    close(messages)
}
围棋编程语言

在并发使用闭包时可能会出现一些混乱。 考虑下面的程序:

func main() {
    done := make(chan bool)

    values := []string{"a", "b", "c"}
    for _, v := range values {
        go func() {
            fmt.Println(v)
            done <- true
        }()
    }

    // wait for all goroutines to complete before exiting
    for _ = range values {
        <-done
    }
}
比如说,

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
)

func getWebPageContent(url string, c chan int, val int) interface{} {
    if r, err := http.Get(url); err == nil {
        defer r.Body.Close()
        if body, err := ioutil.ReadAll(r.Body); err == nil {
            c <- val
            return string(body)
        }
    } else {
        fmt.Println(err)
    }
    return "XoX"
}

const MAX_TH = 40

func main() {

    // pln := fmt.Println
    messages := make(chan int)
    for j := 0; j < MAX_TH; j++ {
        j := j
        go func() { getWebPageContent("http://www.example.com", messages, j) }()
    }

    routine_count := 0
    var page_number int
    for {
        page_number = <-messages
        routine_count++
        fmt.Println("Page number: ", page_number)
        if routine_count == MAX_TH {
            break
        }
    }
    close(messages)
}

我的第一个咕噜回答,可能是完全关了:-)

循环可能如下所示:

...
for j := 0; j < MAX_TH; j++ {
    go func(x) { getWebPageContent("http://www.example.com", messages, x) }(j)
}
...
。。。
对于j:=0;j

基本上,您可以定义一个匿名函数并使用参数调用它。您可以用不同的方法来实现它,但此解决方案看起来非常实用且圆滑:-)

我的第一个golang回复可能完全关闭:-)

循环可能如下所示:

...
for j := 0; j < MAX_TH; j++ {
    go func(x) { getWebPageContent("http://www.example.com", messages, x) }(j)
}
...
。。。
对于j:=0;j

基本上,您可以定义一个匿名函数并使用参数调用它。您可以使用不同的方法,但此解决方案看起来非常实用且圆滑:-)

您应该阅读我的答案。您发布的答案在我发布的常见问题解答中:“要在每个闭包启动时将当前值v绑定到它,必须在每次迭代中修改内部循环以创建新变量。一种方法是将变量作为参数传递给闭包。“示例是常见问题解答中的第二个代码片段。因此您的答案需要一个‘tl;dr’部分,然后:-)您应该已经阅读了我的答案。您发布的答案在我发布的常见问题解答中:“若要在每个闭包启动时将当前值v绑定到闭包,必须在每次迭代中修改内部循环以创建新变量。一种方法是将变量作为参数传递给闭包。”示例是常见问题解答中的第二个代码片段。因此,您的答案需要“tl;dr”部分:-)
...
for j := 0; j < MAX_TH; j++ {
    go func(x) { getWebPageContent("http://www.example.com", messages, x) }(j)
}
...