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

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

One data in Channel received by two routine

问题

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

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "time"
  6. )
  7. func timeout(duration int, ch chan<- bool) {
  8. time.AfterFunc(time.Duration(duration)*time.Second, func() {
  9. ch <- true
  10. })
  11. }
  12. func watcher(duration int, ch <-chan bool) {
  13. <-ch
  14. fmt.Println("\n超时!", duration, "秒后没有回应")
  15. os.Exit(0)
  16. }
  17. func watcher2(duration int, ch <-chan bool) {
  18. <-ch
  19. fmt.Println("这是第二个接收器 watcher2")
  20. }
  21. func main() {
  22. var data = make(chan bool)
  23. var duration = 5
  24. go timeout(duration, data)
  25. go watcher(duration, data)
  26. go watcher2(duration, data)
  27. var input string
  28. fmt.Print("725/25等于多少?")
  29. fmt.Scan(&input)
  30. if input == "29" {
  31. fmt.Println("正确")
  32. } else {
  33. fmt.Println("错误!")
  34. }
  35. }

这段代码使用了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 :

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. &quot;os&quot;
  5. &quot;time&quot;
  6. )
  7. func timeout(duration int, ch chan&lt;- bool) {
  8. time.AfterFunc(time.Duration(duration)*time.Second, func() {
  9. ch &lt;- true
  10. })
  11. }
  12. func watcher(duration int, ch &lt;-chan bool) {
  13. &lt;-ch
  14. fmt.Println(&quot;\nTimeout! no Answer after&quot;, duration, &quot;seconds&quot;)
  15. os.Exit(0)
  16. }
  17. func watcher2(duration int, ch &lt;-chan bool) {
  18. &lt;-ch
  19. fmt.Println(&quot;This is watcher 2 as a second receiver&quot;)
  20. }
  21. func main() {
  22. var data = make(chan bool)
  23. var duration = 5
  24. go timeout(duration, data)
  25. go watcher(duration, data)
  26. go watcher2(duration, data)
  27. var input string
  28. fmt.Print(&quot;What is 725/25 ? &quot;)
  29. fmt.Scan(&amp;input)
  30. if input == &quot;29&quot; {
  31. fmt.Println(&quot;Correct&quot;)
  32. } else {
  33. fmt.Println(&quot;Wrong!&quot;)
  34. }
  35. }

Can you tell me some explanation about it?
Thank you

答案1

得分: 1

如@Andy Schweig所提到的,你只能从Go通道中拉取一次。如果你仍然想要接收两次消息,你可以使用观察者设计模式:

  1. import "fmt"
  2. type Observer interface {
  3. Notify(message string)
  4. }
  5. type Watcher struct {
  6. name string
  7. }
  8. func (w Watcher) Notify(message string) {
  9. fmt.Printf("Watcher %s got message %s\n", w.name, message)
  10. }
  11. var watchers = [...]Watcher{{name: "Watcher 1"}, {name: "Watcher 2"}}
  12. var c = make(chan string)
  13. func notifier() {
  14. var message string
  15. for {
  16. // 消息只被拉取一次
  17. message = <-c
  18. // 但是所有的观察者仍然会收到它
  19. for _, w := range watchers {
  20. w.Notify(message)
  21. }
  22. }
  23. }
  24. func main() {
  25. go notifier()
  26. c <- "hello"
  27. c <- "how are you?"
  28. }

以上是代码的翻译结果。

英文:

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:

  1. import &quot;fmt&quot;
  2. type Observer interface {
  3. Notify(message string)
  4. }
  5. type Watcher struct {
  6. name string
  7. }
  8. func (w Watcher) Notify(message string) {
  9. fmt.Printf(&quot;Watcher %s got message %s\n&quot;, w.name, message)
  10. }
  11. var watchers = [...]Watcher {{name: &quot;Watcher 1&quot;}, {name: &quot;Watcher 2&quot;}}
  12. var c = make(chan string)
  13. func notifier() {
  14. var message string
  15. for {
  16. // Messaged pulled only once
  17. message = &lt;- c
  18. // But all watchers still receive it
  19. for _, w := range watchers {
  20. w.Notify(message)
  21. }
  22. }
  23. }
  24. func main() {
  25. go notifier()
  26. c &lt;- &quot;hello&quot;
  27. c &lt;- &quot;how are you?&quot;
  28. }

答案2

得分: 1

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

  1. 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.

  1. 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:

确定