如何使用 Channels 使 goroutines 相互通信

我是 Golang 的新手,我正在尝试使用 goroutines 以便他们可以在它们之间进行对话。我有一些代码可以启动一个具有 operation1 的 goroutine,我称它为跳舞。当它完成时,它会向另一个执行另一个操作 2 的 goroutine 发出信号,比如说睡眠。


您可以将强制舞蹈参数传递给舞蹈 goroutine,但如果它已经处于舞蹈状态,它将休眠。


package main


import (

    "fmt"

    "time"

)


func main(){

    test("notdancing", true)

    time.Sleep(10*time.Second)

}

func dance()error{

    fmt.Println("Tapping my feet")

    time.Sleep(10*time.Second)

    return nil

}

func test(status string, forceDance bool) {

这不起作用时


   //startSleep := make(chan bool)

为什么需要为通道提供缓冲区长度才能使其工作?我尝试不使用缓冲区长度,但如果我不将 1 作为第二个参数传递,它会说所有 goroutine 都处于睡眠状态。


    startdance := make(chan bool, 1)

    startSleep := make(chan bool, 1)


    if status == "dancing" && forceDance {

        select {

        case startSleep <-true:

            fmt.Println("Would start to sleep now")

        default:

            fmt.Println("Sleep Already started. No need to force")

        }

    }


    if status != "dancing" {

        fmt.Println("Startingdance")

        startdance <- true

    }


    go func() {

        <-startdance

        err := dance()

        if err == nil {

            select {

            case startSleep <- true:

                fmt.Println("Starting Sleeping, dancing completed")

            default:

                fmt.Println("Already started Sleeping")

            }

        } else {

            fmt.Println("Not in a mood to dance today")

        }

    }()


    go func() {

        <-startSleep

        if forceDance {

            fmt.Println("Force sleep because forcing to dance while already dancing")

        }

    }()


}

我非常感谢对代码的任何更正以及使用这种方法的缺陷。


胡子哥哥
浏览 137回答 1
1回答

绝地无双

在无缓冲通道的情况下(未指定大小时)它不能保存一个值,因为它没有大小。因此,在通过通道写入/传输数据时必须有读取器在场,否则它将阻塞调用。func main() {&nbsp; &nbsp; startDance := make(chan bool)&nbsp; &nbsp; startDance <- true}但是当您在上面的代码中指定一个大小(比如 1)时,它不会是死锁,因为它将有空间来保存数据。(((https://robertbasic.com/blog/buffered-vs-unbuffered-channels-in-golang/)。)(https://www.golang-book.com/books/intro/10)你可以看看上面的网站是为了更好地了解通道和并发package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "time")func main() {&nbsp; &nbsp; startDance := make(chan bool)&nbsp; &nbsp; startSleep := make(chan bool)&nbsp; &nbsp; forceSleep := make(chan bool)&nbsp; &nbsp; go startDance1(startDance, forceSleep, startSleep)&nbsp; &nbsp; go performSleep(startSleep, startDance)&nbsp; &nbsp; startDance <- true&nbsp; &nbsp; fmt.Println("now dance is started ")&nbsp; &nbsp; forceSleep <- true&nbsp; &nbsp; select {}}func startDance1(startDance chan bool, forceSleep chan bool, startSleep chan bool) {&nbsp; &nbsp; fmt.Println("waiting to start dance")&nbsp; &nbsp; select {&nbsp; &nbsp; case <-startDance:&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("staring dance")&nbsp; &nbsp; }&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <-startDance:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("starting dance")&nbsp; &nbsp; &nbsp; &nbsp; case <-forceSleep:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("aleardy dancing going to sleep")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case startSleep <- true:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //this is just to show working this&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // i added default or else this will go into deadlock&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("dancing")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(time.Second * 1)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}func performSleep(startSleep chan bool, startDance chan bool) {&nbsp; &nbsp; select {&nbsp; &nbsp; case <-startSleep:&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("staring sleep")&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Println("sleeping for 5 seconds ")&nbsp; &nbsp; time.Sleep(time.Second * 5)&nbsp; &nbsp; select {&nbsp; &nbsp; case startDance <- true:&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("started dance")&nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("failed to start dance ")&nbsp; &nbsp; }}上面的代码是对你的一个小的改进(我试图根据你的要求来做)。我建议您阅读一些书籍以了解有关 Go 并发性的更多信息(https://www.golang-book.com/books/intro/10_
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go