我正面临着一个问题,即使在论坛上度过了一天,我仍然不能完全理解和解决。
在这里,我创建了一个函数,它循环遍历所有的文件夹以及它的子文件夹,它有两个子函数:-对于找到的每个文件,列出文件的名称。-对于找到的每个文件夹,重新启动相同的父函数以再次查找子文件和文件夹。
为了简单起见,宏列出了具有递归的树中的所有文件。但我的目标是尽快做到这一点,所以每当我遇到一个新文件夹时,我都会运行一个新的大猩猩。
问题:
我的问题是当树结构太大时(文件夹和子文件夹中的文件夹太多.)脚本生成了太多的线程,因此给出了一个错误。所以我增加了这个限制,但是突然之间,pc不再想要了
因此,我的问题是,如何使一个符合我的代码的工作系统(具有池大小)?不管我看了多少,我都不知道该怎么说,例如,如何生成新的大猩猩,直到一定的限度,空出缓冲区的时间。
源代码:
https://github.com/LaM0uette/FilesDIR/tree/V0.5
主要:
package main
import (
"FilesDIR/globals"
"FilesDIR/task"
"fmt"
"log"
"runtime/debug"
"sync"
"time"
)
func main() {
timeStart := time.Now()
debug.SetMaxThreads(5 * 1000)
var wg sync.WaitGroup
// task.DrawStart()
/*
err := task.LoopDir(globals.SrcPath)
if err != nil {
log.Print(err.Error())
}
*/
err := task.LoopDirsFiles(globals.SrcPath, &wg) // globals.SrcPath = My path with ~2000000 files ( this is a serveur of my entreprise)
if err != nil {
log.Print(err.Error())
}
wg.Wait()
fmt.Println("FINI: Nb Fichiers: ", task.Id)
timeEnd := time.Since(timeStart)
fmt.Println(timeEnd)
}
任务:
package task
import (
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"sync"
"time"
)
var Id = 0
// LoopDir TODO: Code à supprimer / Code to delete
func LoopDir(path string) error {
var wg sync.WaitGroup
countDir := 0
err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
wg.Add(1)
countDir++
go func() {
err := loopFiles(path, &wg)
if err != nil {
log.Println(err.Error())
}
}()
}
return nil
})
if err != nil {
return err
}
wg.Wait()
fmt.Println("Finished", countDir, Id)
return nil
}
// loopFiles TODO: Code à supprimer / Code to delete
func loopFiles(path string, wg *sync.WaitGroup) error {
files, err := ioutil.ReadDir(path)
if err != nil {
wg.Done()
return err
}
for _, file := range files {
if !file.IsDir() {
go fmt.Println(file.Name())
Id++
}
}
wg.Done()
return nil
}
func LoopDirsFiles(path string, wg *sync.WaitGroup) error {
wg.Add(1)
defer wg.Done()
files, err := ioutil.ReadDir(path)
if err != nil {
return err
}
for _, file := range files {
if !file.IsDir() && !strings.Contains(file.Name(), "~") {
fmt.Println(file.Name(), Id)
Id++
} else if file.IsDir() {
go func() {
err = LoopDirsFiles(filepath.Join(path, file.Name()), wg)
if err != nil {
log.Print(err)
}
}()
time.Sleep(20 * time.Millisecond)
}
}
return nil
}
发布于 2022-04-06 14:13:53
如果您不想使用任何外部包,您可以为文件处理创建一个单独的工作例程,然后开始您想要的工作人员。然后,在主线程中递归地进入树,并将作业发送给工人。如果任何员工“有时间”,它将从作业通道获取以下作业并处理它。
var (
wg *sync.WaitGroup
jobs chan string = make(chan string)
)
func loopFilesWorker() error {
for path := range jobs {
files, err := ioutil.ReadDir(path)
if err != nil {
wg.Done()
return err
}
for _, file := range files {
if !file.IsDir() {
fmt.Println(file.Name())
}
}
wg.Done()
}
return nil
}
func LoopDirsFiles(path string) error {
files, err := ioutil.ReadDir(path)
if err != nil {
return err
}
//Add this path as a job to the workers
//You must call it in a go routine, since if every worker is busy, then you have to wait for the channel to be free.
go func() {
wg.Add(1)
jobs <- path
}()
for _, file := range files {
if file.IsDir() {
//Recursively go further in the tree
LoopDirsFiles(filepath.Join(path, file.Name()))
}
}
return nil
}
func main() {
//Start as many workers you want, now 10 workers
for w := 1; w <= 10; w++ {
go loopFilesWorker()
}
//Start the recursion
LoopDirsFiles(globals.SrcPath)
wg.Wait()
}
https://stackoverflow.com/questions/71766816
复制相似问题