gpt4 book ai didi

mysql - 类型接口(interface)的 channel 在带有 MySql 的 golang 中不接收值

转载 作者:数据小太阳 更新时间:2023-10-29 03:26:47 26 4
gpt4 key购买 nike

我是 golang 的新手。我正在尝试使用 golang 对 mysql db 进行并发查询。我知道 channel 可以是接口(interface)类型。当我在 RunQuery 函数中打印 tableData (type map) 时,我得到了结果。我正在将 tableData 发送到 ch,即接口(interface)类型的 channel 。在函数 getdataList 中,我没有在 ch 中获得任何值。我不明白我做错了什么。

以下是我的代码:

package main

import (
"database/sql"
"fmt"
"net/http"
_ "github.com/go-sql-driver/mysql"
"log"
)


var db *sql.DB

func getdataList(id int) {
ch := make(chan interface{})
done := make (chan bool)
RunQuery(ch,"select id,name, last_name,first_name from persons where id= ?", id)
go func() {
for {
x, ok := <-ch //I am not getting any data in channel here
if ok {
fmt.Println(x)
}else {
fmt.Println("done")
done <- true
return
}

}
}()
}

func RunQuery (ch chan interface{}, query string, param interface{}) {

stmt, err := db.Prepare(query)
if err != nil {
panic(err.Error())
}
defer stmt.Close()
rows, err := stmt.Query(param)
columns, err := rows.Columns()
if err != nil {
fmt.Println("Failed to get columns", err)
return
}
count := len(columns)
tableData := make([]map[string]interface{}, 0)
values := make([]interface{}, count)
valuePtrs := make([]interface{}, count)
for rows.Next() {
for i := 0; i < count; i++ {
valuePtrs[i] = &values[i]
}
rows.Scan(valuePtrs...)
entry := make(map[string]interface{})
for i, col := range columns {
var v interface{}
val := values[i]
b, ok := val.([]byte)
if ok {
v = string(b)
} else {
v = val
}
entry[col] = v
}
tableData = append(tableData, entry)
}
fmt.Pritln(tableData) //here I am getting data in map
ch <- tableData
}


func dbtest(w http.ResponseWriter, req *http.Request) {

go getdataList(2)
go getdataList(3)
}

func main() {
var err error
db, err = sql.Open("mysql", "root:@/dbName")
if err != nil {
panic(err.Error())
}
defer db.Close()

http.HandleFunc("/dbTest", dbtest)

log.Fatal(http.ListenAndServe(":8080", nil))

}

最佳答案

您的代码的问题在于它在从 channel 读取数据之前阻塞了执行流程。当您从 getdataList 调用 RunQuery 时,RunQuery 会尝试通过 channel ch 发送数据。但是,没有从 ch 中读取任何内容,因为要从中读取的代码位于 getdataList 中,并且在对 RunQuery 的调用之下。

因此,RunQuery 永远不会返回,并且从 ch 读取的 goroutine 也永远不会触发。要修复,您也可以尝试将 RunQuery 作为 goroutine 运行:

func getdataList(id int) {
ch := make(chan interface{})
done := make (chan bool)
// run in a goroutine
go RunQuery(ch,"select id,name, last_name,first_name from persons where id= ?", id)
go func() {
for {
x, ok := <-ch //I am not getting any data in channel here
if ok {
fmt.Println(x)
}else {
fmt.Println("done")
done <- true
return
}

}
}()
}

您的代码中还有另一个问题。您永远不会关闭 ch。这可能会导致死锁。执行此操作的最理想位置似乎是在 RunQuery 中:

func RunQuery (ch chan interface{}, query string, param interface{}) {
// ...
ch <- tableData
close(ch)
}

关于mysql - 类型接口(interface)的 channel 在带有 MySql 的 golang 中不接收值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39117702/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com