英文:
Go: all goroutines are asleep - deadlock
问题
这段代码的问题可能出在goroutine的使用上。根据输出信息,所有的goroutine都处于休眠状态,导致死锁。可能的原因是goroutine没有正确地接收到通道的值。
在proccesFileName
函数中,你应该将filename
作为参数传递给匿名函数,而不是在循环中直接使用。这样可以确保每个goroutine都使用不同的filename
值。
修改后的代码如下:
for _, filename := range file_names {
go func(filename string) {
proccesFileName(filename, c, ce)
}(filename)
}
这样修改后,每个goroutine都会接收到不同的filename
值,避免了竞争条件和死锁问题。
另外,你还可以考虑使用sync.WaitGroup
来等待所有的goroutine完成任务,以避免使用无限循环和死锁的问题。具体的实现方式可以参考Go语言的官方文档中关于sync
包的介绍。
希望这些信息对你有帮助!如果还有其他问题,请随时提问。
英文:
<br>
I have snippet of code to resizing images.
<br>
I'm using resize
lib.
<br>
Here is the snippet:
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
}
}
}
And here is my proccesFileName
function:
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)
}
}
And I have the output:
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
Where may be the problem?
答案1
得分: 1
你不需要无限期地等待。你知道消息将会在这些通道上。
for _ = range file_names {
select {
case str := <-c:
fmt.Println(str)
case err := <-ce:
fmt.Println(err)
}
}
英文:
You need not to wait indefinitely. You know how messages will be on the channels.
for _ = range file_names {
select {
case str := <-c
fmt.Println(str)
case err := <-ce
fmt.Println(err)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论