Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

golang: how to print data from running goroutine at fixed intervals?

Tags:

go

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.

like image 737
netbrain Avatar asked Nov 15 '13 20:11

netbrain


People also ask

Can you print Goroutine?

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.

How do you get data from a Goroutine?

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.

How do you know when a Goroutine is going to stop?

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.

How do you communicate between two Goroutines?

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.


1 Answers

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())
        }
    }
}
like image 137
Kluyg Avatar answered Oct 19 '22 23:10

Kluyg