=== 一个 golang goroutine 相关的问题 ===

查看 72|回复 6
作者:FreeWong   
package main
import (
        "fmt"
        "io"
        "net/http"
)
func fetch(url string) string {
        resp, err := http.Get(url)
        if err != nil {
                return err.Error()
        }
        defer resp.Body.Close()
        written, err := io.Copy(io.Discard, resp.Body)
        if err != nil {
                return err.Error()
        }
        result := fmt.Sprintf("%s %s %d", url, resp.Status, written)
        return result
}
func request() string {
        ch := make(chan string)
        go func() {
                ch
这里假设 163.com goroutine 总是第一个执行完,此后 request 函数执行返回。
此时,进程未退出,另外两个 goroutine 仍将把 fetch 的结果发送到 ch ,但是由于 ch 是无缓存的,同时又因为 request 已经返回,
无人从 ch 中接收数据,所以另两个 goroutine 应该会死锁,一直无法退出才是。
但是实际执行时错不报错,这是为什么?多谢
povsister   
先不吐槽标题了。
你这个问题很简单,因为卡死的不是“主线程”。
main 能不能 exit 和其他线程又没关系,只要主线程退出就行,操作系统会负责给你擦屁股的。
PTLin   
在 go 的角度,只有这样的代码才算是死锁
func main() {
ch:=make(chan int)
go func () {
ch<-1
}()
ch<-2
}
wen20   
ch 是为 goroutine 通信设计, 如果 goroutine 写 ch 报错,那,,,等于把 go 语言脑袋砍成了 o 语言。
PTLin   
准确来讲,我理解的 go 中只有所有 goroutine 都因为等待 go 的同步原语( mutex chan 等)而陷入休眠,这时才会运行时报错。
所以在 go 的角度里,你 main 没有因为等待同步原语休眠,所以没问题。
例如这段代码,只有 sleep 结束才会运行时报错死锁,因为这时的两个 goroutine 都等待同步原语 chan 而休眠。
import "time"
func main() {
ch:=make(chan int)
go func () {
ch<-1
}()
go func() {
time.Sleep(time.Second*10)
}()
ch<-2
}
mainjzb   
另两个 goroutine 阻塞了,一直无法退出
直到整个进程结束
wxq844688550   
result := <-ch 有一个协程跑完,ch 中就有值了,有了值这里就不会阻塞了,就会执行下面的 return ,然后整个程序就跑完了,根本不会等剩下两个跑完。你这种情况应该使用 sync.waitgroup
您需要登录后才可以回帖 登录 | 立即注册

返回顶部