2014-12-04 147 views
0


我有片段的代码来调整图像大小。
我正在使用resize lib。
下面是摘录:转:所有goroutines睡着了 - 死锁

package main 

import (
    "fmt" 
    "github.com/nfnt/resize" 
    "image" 
    "image/jpeg" 
    "os" 
    "runtime" 
) 

func main() { 
    runtime.GOMAXPROCS(4) 

    file_names := make([]string, 5) 
    for i := 1; i < 6; i++ { 
     file_names[i-1] = fmt.Sprintf("%v", i) 
    } 

    c := make(chan string) 
    ce := make(chan error) 

    for _, filename := range file_names { 
     go func() { 
      proccesFileName(filename, c, ce) 
     }() 
    } 

    for { 
     select { 
     case str := <-c: 
      fmt.Println(str) 
      break 
     case err := <-ce: 
      fmt.Println(err) 
      break 
     } 
    } 
} 

这里是我的proccesFileName功能:

func proccesFileName(filename string, c chan string, ce chan error) { 
    file, err := os.Open(fmt.Sprintf("in/%v.jpg", filename)) 
    if err != nil { 
     ce <- err 
    } 
    defer file.Close() 

    img, err := jpeg.Decode(file) 
    if err != nil { 
     ce <- err 
    } 

    scales := []float32{1.0, 0.8, 0.6, 0.5, 0.25, 0.01} 
    thumbs := make([]image.Image, len(scales)) 
    for i := 0; i < len(scales); i++ { 
     thumbs[i] = resize.Resize(uint(float32(img.Bounds().Max.X)*scales[i]), 
      uint(float32(img.Bounds().Max.Y)*scales[i]), img, resize.Lanczos3) 

     thumb_name := fmt.Sprintf("out/%v_thumb_%v.jpg", filename, i+1) 

     out, err := os.Create(thumb_name) 
     if err != nil { 
      ce <- err 
     } 
     defer out.Close() 

     jpeg.Encode(out, thumbs[i], nil) 

     c <- fmt.Sprintf("%v FINISHED", i) 
    } 
} 

和我有输出:

0 FINISHED 
0 FINISHED 
0 FINISHED 
0 FINISHED 
0 FINISHED 
1 FINISHED 
1 FINISHED 
1 FINISHED 
2 FINISHED 
1 FINISHED 
1 FINISHED 
2 FINISHED 
3 FINISHED 
2 FINISHED 
2 FINISHED 
2 FINISHED 
3 FINISHED 
4 FINISHED 
4 FINISHED 
3 FINISHED 
5 FINISHED 
3 FINISHED 
5 FINISHED 
3 FINISHED 
4 FINISHED 
4 FINISHED 
4 FINISHED 
5 FINISHED 
5 FINISHED 
5 FINISHED 
fatal error: all goroutines are asleep - deadlock! 

goroutine 16 [select]: 
main.main() 
    /home/cnaize/Desktop/test/main.go:30 +0x509 

goroutine 19 [finalizer wait]: 
runtime.park(0x413ee0, 0x5b2f70, 0x5b1a89) 
    /usr/local/go/src/pkg/runtime/proc.c:1369 +0x89 
runtime.parkunlock(0x5b2f70, 0x5b1a89) 
    /usr/local/go/src/pkg/runtime/proc.c:1385 +0x3b 
runfinq() 
    /usr/local/go/src/pkg/runtime/mgc0.c:2644 +0xcf 
runtime.goexit() 
    /usr/local/go/src/pkg/runtime/proc.c:1445 
exit status 2 

哪里可能是问题?

+2

'breaks'退出'select'语句,而不是'for'。即使在所有工作人员完成后,for循环都会重置,并且会有一个新的select选项挂在通道上,这些选项永远不会收到任何值 – Makpoc 2014-12-04 13:28:19

回答

1

您不必无限等待。你知道信息将如何在渠道上。

for _ = range file_names { 
    select { 
    case str := <-c 
     fmt.Println(str) 
    case err := <-ce 
     fmt.Println(err) 
    } 
}