smo*_*ums 0 concurrency channel go
这段代码用于我的编程语言类的一个相当简单的演示.我试图显示Go允许的一些不同的技术,比如接口和并发,但我似乎无法让WaitGroups正常工作,所以它最终会让我陷入僵局.我最大的问题是:当goroutines停止时,如何让WaitGroups正确同步并且不会使系统死锁?我很可能错过了一些明显的东西.
package main
import (
"bufio"
"fmt"
"os"
"sync"
)
func Reader(wg *sync.WaitGroup, message chan string, done chan bool){
defer wg.Done()
reader := bufio.NewReader(os.Stdin)
for {
msg, _ := reader.ReadString('\n')
if msg == "exit\n" {
<-done
return
} else {
message <- msg
}
}
}
func main() {
message := make(chan string)
done := make(chan bool)
wg := &sync.WaitGroup{}
wg.Add(1)
go Reader(wg, message, done)
wg.Add(1)
go func(){
defer wg.Done()
for {
select {
case <-done:
return
case msg := <-message:
fmt.Println("main: "+msg)
}
}
}()
wg.Wait()
close(message)
close(done)
}
Run Code Online (Sandbox Code Playgroud)
main中的break语句会中断select,而不是for循环.使用return或标签代替:
go func() {
defer wg.Done()
for {
select {
case <-done:
return // don't break here without label
case msg := <-message:
fmt.Println("main: " + msg)
}
}
}()
Run Code Online (Sandbox Code Playgroud)
此外,这两个功能都试图从完成接收.读者应该关闭频道而不是表示完成:
func Reader(wg *sync.WaitGroup, message chan string, done chan bool) {
defer wg.Done()
defer close(done) // close channel to signal completion
reader := bufio.NewReader(os.Stdin)
for {
msg, _ := reader.ReadString('\n')
if msg == "exit\n" {
return
} else {
message <- msg
}
}
}
Run Code Online (Sandbox Code Playgroud)
不要关闭主要通道.频道应始终在发送方侧关闭.
完成所有这些后,您应该认识到该消息已完成并且已完成.整个程序可以简化为:
package main
import (
"bufio"
"fmt"
"os"
)
func Reader(message chan string) {
defer close(message)
reader := bufio.NewReader(os.Stdin)
for {
msg, _ := reader.ReadString('\n')
if msg == "exit\n" {
return
} else {
message <- msg
}
}
}
func main() {
message := make(chan string)
go Reader(message)
for msg := range message {
fmt.Println("main: " + msg)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
54 次 |
| 最近记录: |