I'm having some trouble understanding channels in golang. As far as I know channels are the correct way to publish data to the console at a given time interval.
So say i have a goroutine that is doing work, and then in my main loop i would like to print data from that goroutine every second.
How would something like this be coded? A simple example would be greatly appreciated.
It uses two channels and two Goroutines to control the progress of printing. The first Goroutine is responsible for printing the letters, and the second is responsible for printing the numbers. The first Goroutine will print the letters in order, and the second will print the numbers in order.
You only need one extera receiving goroutine e.g. getData and then the main goroutine will send the data as it arrives using a channel named ch , and you need one buffered channel for signalling e.g. batchCompleted , and a WaitGroup to wait for the getData synchronization, when it is done.
Typically, you pass the goroutine a (possibly separate) signal channel. That signal channel is used to push a value into when you want the goroutine to stop. The goroutine polls that channel regularly. As soon as it detects a signal, it quits.
Go provides a way for bidirectional communication between two goroutines through channels. Bidirectional communication means either party can send or receive a message, so Go provides channels as the mechanism to send or receive data between goroutines. With limitchannel <- i , the value of i enters the channel. fmt.
You can have some protected shared state in memory that you update from your long running process. Then you have a timer that triggers this shared state check every second. Here is a quick example: http://play.golang.org/p/gfGvhHUWIc
Code:
package main
import (
"fmt"
"sync"
"time"
)
type Progress struct {
current string
rwlock sync.RWMutex
}
func (p *Progress) Set(value string) {
p.rwlock.Lock()
defer p.rwlock.Unlock()
p.current = value
}
func (p *Progress) Get() string {
p.rwlock.RLock()
defer p.rwlock.RUnlock()
return p.current
}
func longJob(progress *Progress) {
i := 0
for {
time.Sleep(100 * time.Millisecond)
i++
progress.Set(fmt.Sprintf("Current progress message: %v", i))
}
}
func main() {
fmt.Println("test")
c := time.Tick(1 * time.Second)
progress := &Progress{}
go longJob(progress)
for {
select {
case <-c:
fmt.Println(progress.Get())
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With