【问题标题】:golang: how to print data from running goroutine at fixed intervals?golang:如何以固定的时间间隔从运行的 goroutine 打印数据?
【发布时间】:2013-11-15 20:00:58
【问题描述】:

我在理解 golang 中的频道时遇到了一些问题。据我所知,通道是在给定时间间隔内将数据发布到控制台的正确方式。

假设我有一个正在工作的 goroutine,然后在我的主循环中我想每秒打印来自该 goroutine 的数据。

如何编码这样的东西?一个简单的例子将不胜感激。

【问题讨论】:

  • 任何 goroutine 都可以随时fmt.Println。不需要通道,尽管您可以使用它们来确保两个 goroutine 不会同时写入。如果您想使用通道每秒中断一次 goroutine,通道写入实际上不会中断任何内容;您必须使用select 来检查来自time.Tick 或其他的消息。因此,我认为我们需要更多地了解您的代码目前的样子,以及您目前无法执行的打印定期更新的哪些方面才能回答。
  • 记住log 包提供了Logger 接口。 “一个 Logger 可以在多个 goroutines 中同时使用;它保证对 Writer 的序列化访问。” golang.org/pkg/log/#Logger

标签: go


【解决方案1】:

您可以在内存中拥有一些受保护的共享状态,您可以从长期运行的进程中更新这些状态。然后你有一个计时器,它每秒触发一次共享状态检查。 这是一个简单的例子:http://play.golang.org/p/gfGvhHUWIc

代码:

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())
        }
    }
}

【讨论】:

  • 恕我直言,sync.RWMutex 作为匿名成员看起来更好,所以你可以用p.Lock() 而不是p.rwlock.Lock():例如play.golang.org/p/2ewAmCCaVu
【解决方案2】:

如果您想将数据从一个例程传递到另一个例程,您可以这样做

package main

import "fmt"

func routine(output chan int) {
    for i := 0; i < 1000; i++ {
        output <- i
    }
    close(output)
}

func main() {
    ch := make(chan int)
    go routine(ch)
    for i := range ch {
        fmt.Printf("%d ", i)
    }
}

但这并不是你想要的,你想要的是每一秒的例行状态。为此,通道不是一个好的解决方案。两个例程之间共享的变量将解决该问题。一个例程更新它,另一个例程每秒读取一次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 2014-02-15
    相关资源
    最近更新 更多