一个数据在通道中被两个例程接收到。

huangapple go评论88阅读模式
英文:

One data in Channel received by two routine

问题

你好,以下是你提供的代码的翻译:

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("\n超时!", duration, "秒后没有回应")
	os.Exit(0)
}

func watcher2(duration int, ch <-chan bool) {
	<-ch
	fmt.Println("这是第二个接收器 watcher2")
}

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("725/25等于多少?")
	fmt.Scan(&input)

	if input == "29" {
		fmt.Println("正确")
	} else {
		fmt.Println("错误!")
	}
}

这段代码使用了goroutine和channel。它创建了一个名为data的布尔类型的channel,并设置了超时时间为5秒。然后,它使用三个goroutine来执行不同的任务。

timeout函数使用time.AfterFunc函数来在指定的时间后向channel发送一个布尔值。

watcher函数从channel中接收一个布尔值,并在接收到值后打印超时消息,并退出程序。

watcher2函数也从channel中接收一个布尔值,并在接收到值后打印一条消息。

main函数中,它启动了三个goroutine来执行timeoutwatcherwatcher2函数。然后,它通过用户输入来获取一个字符串,并根据输入的值打印相应的消息。

希望这能对你有所帮助!

英文:

Hello i learn about go routine and channel.
I do some experiment with channel, i send a data over channel and try to catch it in 2 functions. But my second function not run

Here is my code :

package main

import (
	&quot;fmt&quot;
	&quot;os&quot;
	&quot;time&quot;
)

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

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

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

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(&quot;What is 725/25 ? &quot;)
	fmt.Scan(&amp;input)

	if input == &quot;29&quot; {
		fmt.Println(&quot;Correct&quot;)
	} else {
		fmt.Println(&quot;Wrong!&quot;)
	}
}

Can you tell me some explanation about it?
Thank you

答案1

得分: 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 {
        // 消息只被拉取一次
        message = <-c

        // 但是所有的观察者仍然会收到它
        for _, w := range watchers {
            w.Notify(message)
        }
    }
}

func main() {
    go notifier()

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

以上是代码的翻译结果。

英文:

As @Andy Schweig mentioned, you can pull from Go channel only once. If you still want to receive message twice, you can use Observer design pattern:

import &quot;fmt&quot;

type Observer interface {
	Notify(message string)
}

type Watcher struct {
	name string
}

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

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

func notifier() {

	var message string
	for {
        // Messaged pulled only once
		message = &lt;- c

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

func main() {
	go notifier()

	c &lt;- &quot;hello&quot;
	c &lt;- &quot;how are you?&quot;
}

答案2

得分: 1

你声明的channel只能处理一个接收器。默认情况下,channelsunbuffered的,这意味着它们只会接受发送操作,如果有相应的接收器来接收发送的值。而buffered channel可以接受一定数量的值,即使没有相应的接收器来接收这些值。如果你想要注入多个输入及其随后的接收操作,你需要将你的channel声明为buffered channel

ch := make(chan bool, n) // n是要缓冲的项目数量
英文:

The channel you declared can only deal with one receiver. By default channels are unbuffered, meaning that they will only accept sends if there is a corresponding receiver to receive the sent value. Whereas a buffered channel accept a limited number of values without a corresponding receiver for those values. If you are looking to inject multiple input and its subsequent receive then you need declare your channel as buffered channel.

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

huangapple
  • 本文由 发表于 2016年10月30日 11:11:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/40325710.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定