我有大量目錄,所有目錄都包含數百到數千個檔案。我想遍歷目錄串列。然后為每個目錄呼叫一個 go 例程,該例程將掃描目錄中的檔案并將每個檔案的路徑添加到作業佇列中,以便處理一組作業。
這是我到目前為止所擁有的:
type AppConfig struct {
UploadPath string `mapstructure:"upload_path"`
LocalPath string `mapstructure:"local_path"`
Bucket string `mapstructure:"bucket"`
}
func consumer(i int, jobs <-chan *ops.Job) {
defer wg.Done()
for job := range jobs {
fmt.Printf("Worker: %v is processing file: %v\n", i, job.Work)
}
}
func producer(jobs chan<- *ops.Job, filesToTransfer []string) {
for i, file := range filesToTransfer {
jobs <- &ops.Job{Id: i, Work: file}
}
}
func main() {
var (
appconfigs map[string]*ops.AppConfig
wg *sync.WaitGroup
)
jobs := make(chan *ops.Job)
// setting up workers
for i := 0; i < 10; i {
wg.Add(1)
go consumer(i, jobs)
}
// adding jobs
for _, values := range appconfigs {
filesToTransfer := ops.ScanUploadPath(values.LocalPath)
go producer(jobs, filesToTransfer)
}
go func() {
wg.Wait()
close(jobs)
}()
}
在我的生產者函式中呼叫close(jobs)之前,我在關閉通道問題上遇到了死鎖和恐慌。我讀到我應該在我的main()中有這個:
go func() {
wg.Wait()
close(jobs)
}()
我真的不明白為什么我需要一個單獨的 goroutine 在我的producer之外。我希望有人能解釋原因。
uj5u.com熱心網友回復:
因為程式在 main 函式回傳時退出,所以將呼叫轉移到 goroutine 掩蓋了問題。
使用此代碼:
// Start workers.
var wg sync.WaitGroup
jobs := make(chan *ops.Job)
for i := 0; i < 10; i {
wg.Add(1)
go consumer(&wg, i, jobs)
}
// Send jobs to the workers.
for _, values := range appconfigs {
filesToTransfer := ops.ScanUploadPath(values.LocalPath)
// Send the jobs from the main goroutine.
// Nothing is gained by using a goroutine
// as in the question.
for i, file := range filesToTransfer {
jobs <- &ops.Job{Id: i, Work: file}
}
}
// Close the channel to signal that all jobs are
// sent.
close(jobs)
// Wait for the workers to complete.
wg.Wait()
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/512007.html
標籤:去协程
