关于 Golang Go语言中协程的一个问题
关于 Golang Go语言中协程的一个问题
需求:
fun main(){
x1(id string) (objectEntity entity, error) {}
x2(id string) (objectEntity []entity, error) {}
x3(id string) (objectEntity entity, error) {}
}
x1(),x2(),x3()分别是三个互相不关联的 3 个 sql 查询.
x1 会返回一个 objectEntity, error, x2 会返回一个[]objectEntity, x3 会返回一个 objectEntity.
我会拿到这 3 个返回值,然后进行拼接.
本来直接使用 goroutine 和 channel 来进行请求.
但是我遇到一个问题, 不管是 x1,x2,x3 进行查询,返回值 都有 error. 大家有什么好的办法吗?
更多关于关于 Golang Go语言中协程的一个问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
“不管是 x1,x2,x3 进行查询,返回值 都有 error” ???
有 error 不就是报错了么,不能先处理了 error 再考虑后面拼接的问题么
具体得看你们容错程度,一个或多个出错了就不参与拼接 还是 不能有 error 必须保证全部有结果才能拼接
再另外说一句,既然要同步拼接,根本不需要走协程,同步执行就行了.异步反而更麻烦
更多关于关于 Golang Go语言中协程的一个问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这个好像和协程没啥关系,要根据你需求来决定吧,比如某个返回值有 error 时用个默认值来代替
再定义一个 channel 处理 error 呗
搞不懂这为什么是协程的问题
至少写个能跑起来的伪代码,让大家跑一下吧… 要不大家都不知道你的代码是咋样的,也无法给你解决问题
xResult {
obj objectEntity
err Error
}
不过我觉得这法子不太标准
第一: 异步还是有必要的, 假如 x1 需要 0.5s x2 需要 0.5s x3 需要 0.8s. 如果同步执行,就需要 1.8s. 异步查询,0.8s 就可以拿到所有的结果. 第二: 查询有错误,是因为所有的 orm 包在查询的时候,都会返回 error 这个值. 我目前抽出来的函数 都没有直接对 error 进行处理.都是返回正常的结果和 error.然后在外层统一处理.
把[]objectEntity 和 error 合成为一个结构体golang<br>type A struct {<br> list []objectEntity<br> err error<br>}<br>
然后错误逻辑放到 service 层做处理
不管有没有协程,不都是应该先处理 error?
只要 error 不是 nil
直接返回给调用者处理就行了
我加了伪代码 求<br>我加了伪代码... 求大家帮忙写个 gorouter<br><br>
func main() {
id := 1
user1, err := x1(id)
if err != nil {
// 处理
}
userList, err := x2(id)
if err != nil {
// 处理
}
user2, err := x3(id)
if err != nil {
// 处理
}
// 然后 user1, userList, user2 进行拼接
}
type User struct {
Id int json:"id"
Name string json:"name"
}
func x1(id int) (User, error) {
var err error
user := User{
Id: 1,
Name: “xx”,
}
return user, err
}
func x2(id int) ([]User, error) {
var err error
user := User{
Id: 1,
Name: “xx”,
}
userList := []User{user, user}
return userList, err
}
func x3(id int) (User, error) {
var err error
var user User
{
}
err = errors.New(“假设出现错误”)
return user, err
}<br><br>
#7
我不知道你用的什么 orm 包,常用的 gorm 查询结果是不可能有 error 的,除非是查询结果不存在会有个"record not found"的 error
异步这个你说的是对的,如果所有查询都正常的话.
粗略想了下你要用 channel 需要就需要把结果和 error 统一包一个结构体.可能用 sync.WaitGroup 更简单一些.
<br>func main() {<br> id := 1<br> user1, err := x1(id)<br> if err != nil {<br> // 处理<br> }<br> userList, err := x2(id)<br> if err != nil {<br> // 处理<br> }<br> user2, err := x3(id)<br> if err != nil {<br> // 处理<br> }<br><br> // 然后 user1, userList, user2 进行拼接<br>}<br><br>type User struct {<br> Id int `json:"id"`<br> Name string `json:"name"`<br>}<br><br>func x1(id int) (User, error) {<br> var err error<br> user := User{<br> Id: 1,<br> Name: "xx",<br> }<br><br> return user, err<br>}<br><br>func x2(id int) ([]User, error) {<br> var err error<br> user := User{<br> Id: 1,<br> Name: "xx",<br> }<br> userList := []User{user, user}<br><br> return userList, err<br>}<br><br>func x3(id int) (User, error) {<br> var err error<br> var user User<br> {<br> }<br> err = errors.New("假设出现错误")<br><br> return user, err<br>}<br><br>
你这用 waitgroup 最合适了
wg.Add(3)
errCh := make(chan error)
userCh := make(chan *User)
go func(){
defer wg.Done()
user, err := x1()
if err != nil {
}
}()
用 errgroup 来做非常简单
https://gist.github.com/icexin/dda98e3c7dbbf2d8b37ef1fc79267197
根本原因还是 error 是什么,对于 error 应该怎么处理,因为三个 err 的含义或者容忍度可能不一样,一起处理感觉是在偷懒。你的问题跟 goroutine 没有什么关系。
一起处理的话上面的那些 xxgroup 的例子可行,但是有点违背 go 的设计原则。因为本质上都是在“通过共享来传递消息”,通过共享几个 data 变量来在 routine 间传递消息不是 golang 推荐的做法。(我不确定现在 golang 还说不说这个设计理念了,好几年没写过 golang 了)
BTW,我觉得你的数据库结构设计的可能有点问题,join 语句效率也没有低到这个程度吧,感觉你在强行拿 goroutine 做一个不必要的优化,“拿着锤子看什么都是钉子”系列。
对此封了一个结构, 欢迎拍砖 https://github.com/mint-leaf/gotokit/tree/master/task
关于Golang中协程(goroutine)的一个问题,很高兴为您提供一些专业见解。
协程是Go语言的一大特色,它提供了一种轻量级的方式来并发执行任务。与传统的线程相比,协程的创建和切换开销非常小,这使得Go程序能够高效地处理大量并发任务。
如果您在使用协程时遇到问题,可能是由以下几个常见原因导致的:
-
资源竞争与死锁:多个协程访问共享资源时,如果没有正确使用同步机制(如互斥锁、通道等),可能会导致数据竞争或死锁。使用
go run -race
命令可以帮助检测数据竞争问题。 -
协程泄漏:如果协程没有正确终止,或者主函数在协程完成前退出,可能会导致协程泄漏。确保所有协程都能正确结束,或者使用
sync.WaitGroup
等工具来等待协程完成。 -
性能瓶颈:虽然协程开销小,但大量协程同时运行也可能导致性能问题。合理使用协程数量,避免过度并发,是优化性能的关键。
-
错误处理:协程中的错误需要特别处理,因为协程之间没有直接的错误传播机制。通常,使用通道(channel)来传递错误或结果是一个好的做法。
针对具体问题,您可以提供更详细的代码示例或错误描述,以便进一步分析和解决。希望这些建议对您有所帮助!