dongnei3634 2015-11-27 13:29
浏览 20
已采纳

使用渠道进行管道

I'm exploring Go and trying to set up a sort of pipeline using channels. I just want to read something in main() and send them to process() for processing, in this case just print the value to the screen.

Unfortunately, in the code below, it appears that process() never reads from the channel, or at least it doesn't print anything; what am I doing wrong?

package main

import ( "fmt" ; "database/sql" ; _ "github.com/lib/pq" ; "time" ; "gopkg.in/redis.v3" )//; "strconv" )

type Record struct {
    userId, myDate int
    prodUrl string
}


func main(){

    //connect to db
    db, err := sql.Open(...)
    defer db.Close()

    //error check here...

    //exec query
    rows, err := db.Query("select userID,url,date from mytable limit 10")
    defer rows.Close()

    //error check here...   

    //create channel to buffer rows read
    bufferChan := make(chan *Record,1000)
    go process(bufferChan)

    //iterate through results and send them to process()
    row := new(Record)
    for rows.Next(){
        err := rows.Scan(&row.userId, &row.prodUrl, &row.myDate)        
        bufferChan <- row
        fmt.Printf("row sent %v",row.userId)                    
    }   
}

//prints Record values
func process (buffer chan *Record) {
    row := <- buffer
    fmt.Printf("row received: %d %v %d ", row.userId,row.prodUrl,row.myDate)
}
  • 写回答

3条回答 默认 最新

  • duanming0494 2015-11-27 14:09
    关注

    The reason for func process not printing anything is that you func main exits after the for loop for rows.Next finishes thereby exiting the program. You need to do couple of things.

    1. Add call to close after for loop to indicate end adding message to buffered channel else it can lead to deadlock. So call close(bufferChan)
    2. Use range to iterate over channel in your func process.
    3. Pass an additional channel to process to know when it finishes so that main can wait till process finishes.

    Look at the code snippet below for example:

    package main
    
    import "fmt"
    
    func main() {
        bufferChan := make(chan int, 1000)
        done := make(chan bool)
        go process(bufferChan, done)
        for i := 0; i < 100; i++ {
            bufferChan <- i
        }
        close(bufferChan)
    
        select {
        case <-done:
            fmt.Println("Done")
        }
    
    }
    
    func process(c chan int, done chan bool) {
        for s := range c {
            fmt.Println(s)
        }   
        done <- true
    
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 python中transformers可以正常下载,但是没有办法使用pipeline
  • ¥50 分布式追踪trace异常问题
  • ¥15 人在外地出差,速帮一点点
  • ¥15 如何使用canvas在图片上进行如下的标注,以下代码不起作用,如何修改
  • ¥15 Windows 系统cmd后提示“加载用户设置时遇到错误”
  • ¥50 vue router 动态路由问题
  • ¥15 关于#.net#的问题:End Function
  • ¥15 无法import pycausal
  • ¥15 weditor无法连接模拟器Local server not started, start with?
  • ¥20 6-3 String类定义