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

如何使用 Channels 让 goroutine 相互通信

如何使用 Channels 让 goroutine 相互通信

Go
狐的传说 2023-08-14 14:51:10
我是 Golang 新手,正在尝试使用 goroutine,以便它们可以在它们之间进行通信。我有一些代码启动一个具有操作 1 的 goroutine,我称之为跳舞。当它完成时,它会向另一个 goroutine 发出信号,该 goroutine 执行另一个操作2,比如说睡眠。您可以将强制舞蹈参数传递给舞蹈 goroutine,但如果它已经处于舞蹈状态,它将休眠。package mainimport (    "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")        }    }()}我非常感谢对代码的任何更正以及使用这种方法的陷阱。
查看完整描述

1 回答

?
30秒到达战场

TA贡献1828条经验 获得超6个赞

在无缓冲通道的情况下(未指定大小时),它无法保存值,因为它没有大小。因此,通过通道写入/传输数据时必须有读取器在场,否则将阻塞调用。


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 main


import (

    "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 ")

    }

}

上面的代码是对你的代码的一个小小的改进(我试图根据你的要求来制作它)。

查看完整回答
反对 回复 2023-08-14
  • 1 回答
  • 0 关注
  • 104 浏览
慕课专栏
更多

添加回答

举报

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