Пинг-Понг: обмен сообщениями между горутинами
Условие задачи
Реализуй простую модель обмена сообщениями между двумя горутинами. Одна горутина отправляет "ping", вторая отвечает "pong" — и так по очереди N раз. Каждое сообщение должно выводиться в stdout. Взаимодействие должно происходить через каналы без использования sleep или shared переменных.
package main
import (
"fmt"
)
func ping(pingCh chan<- string, pongCh <-chan string, n int) {
// TODO: отправляй "ping" и жди "pong"
}
func pong(pingCh <-chan string, pongCh chan<- string) {
// TODO: жди "ping" и отвечай "pong"
}
func main() {
pingCh := make(chan string)
pongCh := make(chan string)
n := 10
go ping(pingCh, pongCh, n)
go pong(pingCh, pongCh)
// TODO: дождись завершения
}
package main
import (
"fmt"
)
func ping(pingCh chan<- string, pongCh <-chan string, n int) {
// TODO: отправляй "ping" и жди "pong"
}
func pong(pingCh <-chan string, pongCh chan<- string) {
// TODO: жди "ping" и отвечай "pong"
}
func main() {
pingCh := make(chan string)
pongCh := make(chan string)
n := 10
go ping(pingCh, pongCh, n)
go pong(pingCh, pongCh)
// TODO: дождись завершения
}
Подсказка
- Используй каналы как способ синхронизации. - Используй цикл с n итерациями внутри ping. - Не забудь завершить программу корректно — можно использовать sync.WaitGroup или просто вызвать os.Exit(0) в конце main (в простом варианте).
Решение
Горутины ping и pong взаимодействуют через два канала. Ping отправляет "ping", ждёт "pong". Pong ждёт "ping", отвечает "pong". Всё это происходит синхронно.
package main
import (
"fmt"
)
func ping(pingCh chan<- string, pongCh <-chan string, n int) {
for i := 0; i < n; i++ {
pingCh <- "ping"
msg := <-pongCh
fmt.Println(msg)
}
close(pingCh)
}
func pong(pingCh <-chan string, pongCh chan<- string) {
for msg := range pingCh {
fmt.Println(msg)
pongCh <- "pong"
}
close(pongCh)
}
func main() {
pingCh := make(chan string)
pongCh := make(chan string)
n := 10
go ping(pingCh, pongCh, n)
go pong(pingCh, pongCh)
for range pongCh {
// ничего не делаем — просто ждём завершения
}
}
package main
import (
"fmt"
)
func ping(pingCh chan<- string, pongCh <-chan string, n int) {
for i := 0; i < n; i++ {
pingCh <- "ping"
msg := <-pongCh
fmt.Println(msg)
}
close(pingCh)
}
func pong(pingCh <-chan string, pongCh chan<- string) {
for msg := range pingCh {
fmt.Println(msg)
pongCh <- "pong"
}
close(pongCh)
}
func main() {
pingCh := make(chan string)
pongCh := make(chan string)
n := 10
go ping(pingCh, pongCh, n)
go pong(pingCh, pongCh)
for range pongCh {
// ничего не делаем — просто ждём завершения
}
}