나는 모든 파일을 폴더 링크에서 스캔하고 자신의 콘텐츠와 이름을 기반으로하는 정규식을 사용하여 자신의 크기로 "톱 10"을 만드는 코드를 만들려고합니다. 파일. 내용으로 볼 때, 나는 goroutine으로 채널을 만들었지 만, 내 goroutine이 잠길 때마다 이유를 이해하지 못합니다. 여기Golang Goroutine 오류 "모든 goroutines이 잠 들어 있습니다 - 교착 상태입니다!"
package main
import (
"flag"
"fmt"
"io/ioutil"
"regexp"
"runtime"
"sort"
"sync"
"time"
)
var rName = ".php"
var rContent = "php"
var maxSize, minSize int64
var files_ten []File
func main() {
start := time.Now()
channelOne := make(chan File)
channelTwo := make(chan File)
var wg sync.WaitGroup
var path string
flag.StringVar(&path, "path", "", "Path to folder")
flag.Parse()
fmt.Println("Path=", path)
for i := 0; i < runtime.NumCPU(); i++ {
go check(channelOne, channelTwo, &wg)
}
go top10(channelTwo, &wg)
wg.Wait()
getFolder(path, channelOne, &wg)
fmt.Println("top 10", files_ten)
t := time.Now()
current := t.Sub(start)
fmt.Println(current)
}
type File struct {
Size int64
Name string
Path string
}
func (this File) GetSize() int64 {
return this.Size
}
func getFolder(path string, channelOne chan File, wg *sync.WaitGroup) {
folder, err := ioutil.ReadDir(path)
if err != nil {
fmt.Println("Error:", err)
return
}
for _, data := range folder {
if data.IsDir() {
var newFolder string = path + data.Name() + "/"
getFolder(newFolder, channelOne, wg)
} else {
wg.Add(1)
channelOne <- File{Size: data.Size(), Name: data.Name(), Path: path}
}
}
}
func check(channelOne chan File, channelTwo chan File, wg *sync.WaitGroup) {
for {
file := <-channelOne
rName := regexp.MustCompile(rName)
maxSize = 10000
minSize = 0
if rName.MatchString(file.Name) {
if file.Size <= maxSize && file.Size >= minSize {
f, err := ioutil.ReadFile(file.Path + "/" + file.Name)
if err != nil {
fmt.Println("Error:", err)
return
}
rContent := regexp.MustCompile(rContent)
if rContent.MatchString(string(f)) {
channelTwo <- file
} else {
wg.Done()
}
} else {
wg.Done()
}
} else {
wg.Done()
}
}
}
func sortFilesFromBiggestToLowerSize(arrayFile []File) []File {
sort.Slice(arrayFile, func(i, j int) bool {
return arrayFile[i].Size > arrayFile[j].Size
})
return arrayFile
}
func top10(channelTwo chan File, wg *sync.WaitGroup) []File {
for {
f := <-channelTwo
if len(files_ten) == 10 {
if f.Size > files_ten[0].Size || f.Size >
files_ten[len(files_ten)-1].Size {
files_ten = files_ten[:len(files_ten)-1]
files_ten = append(files_ten, f)
return sortFilesFromBiggestToLowerSize(files_ten)
}
} else {
sortFilesFromBiggestToLowerSize(files_ten)
return append(files_ten, f)
}
wg.Done()
return files_ten
}
}
오류가 나는 컴파일 할 때마다한다 : 여기 내 코드는
go run filebysize.go --path=C:/wamp64/www/symfony/init/cours1/
Path= C:/wamp64/www/symfony/init/cours1/
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.getFolder(0xc04210a3c0, 0x3d, 0xc04204c0c0, 0xc04204e210)
C:/Users/Sahra/Documents/go/display/filebysize.go:72 +0x28a
main.getFolder(0xc04210a200, 0x32, 0xc04204c0c0, 0xc04204e210)
C:/Users/Sahra/Documents/go/display/filebysize.go:69 +0x151
main.getFolder(0xc04200e6c0, 0x26, 0xc04204c0c0, 0xc04204e210)
C:/Users/Sahra/Documents/go/display/filebysize.go:69 +0x151
main.getFolder(0xc042051f57, 0x22, 0xc04204c0c0, 0xc04204e210)
C:/Users/Sahra/Documents/go/display/filebysize.go:69 +0x151
main.main()
C:/Users/Sahra/Documents/go/display/filebysize.go:37 +0x2e0
goroutine 19 [chan send]:
main.check(0xc04204c0c0, 0xc04204c120, 0xc04204e210)
C:/Users/Sahra/Documents/go/display/filebysize.go:95 +0x2ec
created by main.main
C:/Users/Sahra/Documents/go/display/filebysize.go:32 +0x26d
goroutine 20 [chan send]:
main.check(0xc04204c0c0, 0xc04204c120, 0xc04204e210)
C:/Users/Sahra/Documents/go/display/filebysize.go:95 +0x2ec
created by main.main
C:/Users/Sahra/Documents/go/display/filebysize.go:32 +0x26d
goroutine 21 [chan send]:
main.check(0xc04204c0c0, 0xc04204c120, 0xc04204e210)
C:/Users/Sahra/Documents/go/display/filebysize.go:95 +0x2ec
created by main.main
C:/Users/Sahra/Documents/go/display/filebysize.go:32 +0x26d
goroutine 22 [chan send]:
main.check(0xc04204c0c0, 0xc04204c120, 0xc04204e210)
C:/Users/Sahra/Documents/go/display/filebysize.go:95 +0x2ec
created by main.main
C:/Users/Sahra/Documents/go/display/filebysize.go:32 +0x26d
goroutine 23 [chan send]:
main.check(0xc04204c0c0, 0xc04204c120, 0xc04204e210)
C:/Users/Sahra/Documents/go/display/filebysize.go:95 +0x2ec
created by main.main
C:/Users/Sahra/Documents/go/display/filebysize.go:32 +0x26d
goroutine 24 [chan send]:
main.check(0xc04204c0c0, 0xc04204c120, 0xc04204e210)
C:/Users/Sahra/Documents/go/display/filebysize.go:95 +0x2ec
created by main.main
C:/Users/Sahra/Documents/go/display/filebysize.go:32 +0x26d
goroutine 25 [chan send]:
main.check(0xc04204c0c0, 0xc04204c120, 0xc04204e210)
C:/Users/Sahra/Documents/go/display/filebysize.go:95 +0x2ec
created by main.main
C:/Users/Sahra/Documents/go/display/filebysize.go:32 +0x26d
goroutine 26 [chan send]:
main.check(0xc04204c0c0, 0xc04204c120, 0xc04204e210)
C:/Users/Sahra/Documents/go/display/filebysize.go:95 +0x2ec
created by main.main
C:/Users/Sahra/Documents/go/display/filebysize.go:32 +0x26d
exit status 2
이것은 이해해야 할 많은 코드이지만, 일부는 보입니다. 'top10'의 반환 값은 무시됩니다. waitgroup은 goroutines를 실행하는 것 이외의 것으로 계산하는 데 사용됩니다. –
당신이 맞습니다. 문제는 함수 톱 10에서 아무것도 반환하지 말고, if else 문에 포함 시키십시오. 고마워요 !!!!!!!!!!!!!!!!!!! !! !! –