如何使用 Channels 让 goroutine 相互通信

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


您可以将强制舞蹈参数传递给舞蹈 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")

        }

    }()


}

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


狐的传说
浏览 75回答 1
1回答

30秒到达战场

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