2 回答

TA貢獻(xiàn)1812條經(jīng)驗(yàn) 獲得超5個(gè)贊
原始代碼不限制活動(dòng) go 例程的數(shù)量,因此不限制打開(kāi)的文件描述符的數(shù)量。一些操作系統(tǒng)對(duì)打開(kāi)的文件描述符的數(shù)量有限制。解決方法是創(chuàng)建固定數(shù)量的工作程序 go 例程。
func uploadDir(path string) error {
// Read directory and close.
dir, err := os.Open(path)
if err != nil {
return err
}
names, err := dir.Readdirnames(-1)
if err != nil {
return err
}
dir.Close()
// Copy names to a channel for workers to consume. Close the
// channel so that workers stop when all work is complete.
namesChan := make(chan string, len(names))
for _, name := range names {
namesChan <- name
}
close(namesChan)
// Create a maximum of 8 workers
workers := 8
if len(names) < workers {
workers = len(names)
}
errChan := make(chan error, 1)
resChan := make(chan *client.PutResult, len(names))
// Run workers
for i := 0; i < workers; i++ {
go func() {
// Consume work from namesChan. Loop will end when no more work.
for name := range namesChan {
file, err := os.Open(filepath.Join(path, name))
if err != nil {
select {
case errChan <- err:
// will break parent goroutine out of loop
default:
// don't care, first error wins
}
return
}
c := client.NewClient(os.Getenv("DROPS_SERVER"))
res, err := c.Upload(client.NewUploadHandleFromReader(file))
file.Close()
if err != nil {
select {
case errChan <- err:
// will break parent goroutine out of loop
default:
// don't care, first error wins
}
return
}
resChan <- res
}
}()
}
// Collect results from workers
for i := 0; i < len(names); i++ {
select {
case res := <-resChan:
log.Println(res)
case err := <-errChan:
return err
}
}
return nil
}
作為獎(jiǎng)勵(lì),我修改了通道大小并發(fā)送操作,以便在出現(xiàn)錯(cuò)誤時(shí)不會(huì)卡住 goroutine。
- 2 回答
- 0 關(guān)注
- 239 瀏覽
添加回答
舉報(bào)