帮忙看看为什么会死锁

humengqiao · · 1159 次点击
<a href="/user/brantou" title="@brantou">@brantou</a> <a href="/user/Hubery" title="@Hubery">@Hubery</a> 嗯,`buf := make([]byte, 100)`应该放在`for`循环中的,一开始只是想回答题主的死锁问题,代码的确有问题
#7
更多评论
你上面的代码真的不忍看,漏洞百出,我修改过的,你看下,地址:https://play.golang.org/p/-qntkhCVVtA
#1
基于你的代码修改,首先`fmt.Println(&lt;-endChan)`会造成`deadlock`,然后`select`中的`break`并不能跳出外层`for`循环,代码如下: ```go package main import ( &#34;bufio&#34; &#34;fmt&#34; &#34;io&#34; &#34;log&#34; &#34;os&#34; &#34;strconv&#34; &#34;time&#34; ) func readData(bfRd io.Reader, dataChan chan []byte, endChan chan error) { buf := make([]byte, 100) for { n, err := bfRd.Read(buf) if err != nil { endChan &lt;- err return } fmt.Printf(&#34;read data %s size \n&#34;, strconv.Itoa(n)) dataChan &lt;- buf } } func main() { file, err := os.Open(&#34;client.go&#34;) if err != nil { log.Fatalln(err) } var data []byte bfRd := bufio.NewReader(file) var dataChan = make(chan []byte) var endChan = make(chan error) go readData(bfRd, dataChan, endChan) L: for { select { case err := &lt;-endChan: fmt.Println(err) break L case &lt;-dataChan: data = append(data, &lt;-dataChan...) case &lt;-time.After(time.Second): fmt.Println(&#34;timeout&#34;) break L default: fmt.Println(&#34;channel cannot use&#34;) } } fmt.Println(string(data)) } ```
#2