【问题标题】:One data in Channel received by two routineChannel 中的一个数据被两个程序接收到
【发布时间】:2017-03-12 13:32:09
【问题描述】:

你好,我了解了 goroutine 和 channel。 我对通道做了一些实验,我通过通道发送数据并尝试在 2 个函数中捕获它。但我的第二个功能没有运行

这是我的代码:

package main

import (
    "fmt"
    "os"
    "time"
)

func timeout(duration int, ch chan<- bool) {
    time.AfterFunc(time.Duration(duration)*time.Second, func() {
        ch <- true
    })
}

func watcher(duration int, ch <-chan bool) {
    <-ch
    fmt.Println("\nTimeout! no Answer after", duration, "seconds")
    os.Exit(0)
}

func watcher2(duration int, ch <-chan bool) {
    <-ch
    fmt.Println("This is watcher 2 as a second receiver")
}

func main() {
    var data = make(chan bool)
    var duration = 5

    go timeout(duration, data)
    go watcher(duration, data)
    go watcher2(duration, data)

    var input string
    fmt.Print("What is 725/25 ? ")
    fmt.Scan(&input)

    if input == "29" {
        fmt.Println("Correct")
    } else {
        fmt.Println("Wrong!")
    }
}

你能告诉我一些关于它的解释吗? 谢谢

【问题讨论】:

  • 在频道上发送的项目只会收到一次。

标签: go channel goroutine


【解决方案1】:

正如@Andy Schweig 所说,您只能从 Go 频道拉取一次。如果你还想接收两次消息,你可以使用观察者设计模式:

import "fmt"

type Observer interface {
    Notify(message string)
}

type Watcher struct {
    name string
}

func (w Watcher) Notify(message string) {
    fmt.Printf("Watcher %s got message %s\n", w.name, message)
}

var watchers =  [...]Watcher {{name: "Watcher 1"}, {name: "Watcher 2"}}
var c = make(chan string)

func notifier() {

    var message string
    for {
        // Messaged pulled only once
        message = <- c

        // But all watchers still receive it
        for _, w := range watchers {
            w.Notify(message)
        }
    }
}

func main() {
    go notifier()

    c <- "hello"
    c <- "how are you?"
}

【讨论】:

    【解决方案2】:

    您声明的channel 只能处理一个接收者。默认情况下channelsunbuffered,这意味着如果有相应的接收者接收发送的值,它们将只接受发送。而buffered 通道接受有限数量的值,而没有相应的接收器接收这些值。如果您希望注入多个输入及其后续接收,则需要将您的 channel 声明为 buffered channel

    ch := make(chan bool, n) //n being the number of items to buffer
    

    【讨论】:

      猜你喜欢
      • 2015-09-07
      • 1970-01-01
      • 2021-02-22
      • 2014-03-10
      • 2016-11-08
      • 1970-01-01
      • 2013-09-03
      • 2020-03-25
      • 2013-02-11
      相关资源
      最近更新 更多