douxianliu6756 2016-10-09 16:27
浏览 60
已采纳

Goroutine在Windows和Linux上的行为有所不同

I`m new to the GO. I have a following legacy code.

var db *sql.DB

func init() {
    go feedChan()

    connString := os.Getenv("DB_CONN")
    var err error

    db, err = sql.Open("postgres", connString)
    if err != nil {
        log.Fatalf("Failed to connect to database at %q: %q
", connString, err)
    }

    // confirm connection
    if err = db.Ping(); err != nil {
        log.Fatalf("Unable to ping database at %q: %q
", connString, err)
    }
}


func feedChan() {
    selectQuery, err := db.Prepare(`
        SELECT id, proxy
        FROM proxy
        WHERE fail_count < 2
        ORDER BY date_added DESC, last_used ASC, fail_count ASC
        LIMIT 5
    `)
    ....

Following code works on linux. But it fails on windows with nil error on

selectQuery, err := db.Prepare(`

Which make sense for me, since db initialized after a launch of feedChan goroutine. What doesnt make sense for me is why it work on linux.

So the question is why this code work at linux without errors?

  • 写回答

2条回答 默认 最新

  • drtiwd06558 2016-10-09 17:03
    关注

    That's probably a race condition. Import "time", put this line after go feedChan(), and see if it still works on Linux:

    time.Sleep(3 * time.Second)
    

    In order to avoid this situation, you could either initialize db before you spawn the routine (which uses db) or use some sort of barrier:

    func init() {
        barrier := make(chan int)
        go feedChan(barrier)
    
        connString := os.Getenv("DB_CONN")
        var err error
        db, err = sql.Open("postgres", connString)
    
        if err != nil {
            log.Fatalf("Failed to connect to database at %q: %q
    ", connString, err)
            // Retry.
        } else {
            barrier <- 1 // Opens barrier.
        }
        // ...
    }
    
    
    func feedChan(barrier chan int) {
        <-barrier // Blocks until db is ready.
        selectQuery, err := db.Prepare(`
            SELECT id, proxy
            FROM proxy
            WHERE fail_count < 2
            ORDER BY date_added DESC, last_used ASC, fail_count ASC
            LIMIT 5
        `)
        // ...
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 安装svn网络有问题怎么办
  • ¥15 Python爬取指定微博话题下的内容,保存为txt
  • ¥15 vue2登录调用后端接口如何实现
  • ¥65 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥15 latex怎么处理论文引理引用参考文献