[日常] Go語言聖經-樣本: 並發的目錄遍曆習題

來源:互聯網
上載者:User

標籤:進度   struct   ges   大小   loop   ogre   ret   progress   wait   

練習 8.9: 編寫一個du工具,每隔一段時間將root目錄下的目錄大小計算並顯示出來。

package mainimport (        //      "filepath"        "flag"        "fmt"        "io/ioutil"        "os"        "path"        "sync"        "time")/*練習 8.9: 編寫一個du工具,每隔一段時間將root目錄下的目錄大小計算並顯示出來。*///接收命令列參數-vvar verbose = flag.Bool("v", false, "show verbose progress messages")func main() {        //接收命令列參數,多個路徑        flag.Parse()        roots := flag.Args()        //如果沒傳遞任何路徑,給預設值        if len(roots) == 0 {                 roots = []string{"/"}        }           for {                sumFileSize(roots)                time.Sleep(20 * time.Second)        }   }func sumFileSize(roots []string) {        //發送和接收檔案位元組大小的channel        fileSizes := make(chan int64)        //goroutine的計數器        var n sync.WaitGroup        //迴圈命令列傳遞的路徑        for _, root := range roots {                n.Add(1)                //啟動goroutine計算                go walkDir(root, &n, fileSizes)        }           //啟動goroutine,等待所有計算目錄的goroutine結束        go func() {                n.Wait()                close(fileSizes)        }()         //定時顯示目錄進度發送的channel        var tick <-chan time.Time        if *verbose {                tick = time.Tick(500 * time.Millisecond)        }           var nfiles, nbytes int64        //select和loop迴圈,多工loop:        for {                select {                case size, ok := <-fileSizes:                        if !ok {                                break loop // fileSizes was closed                        }                        //計算目錄數,計算位元組大小                        nfiles++                        nbytes += size                case <-tick:                        //接收到定時channel列印進度                        printDiskUsage(nfiles, nbytes)                }        }        //最後列印總計        printDiskUsage(nfiles, nbytes) // final totals}func walkDir(dir string, n *sync.WaitGroup, fileSizes chan<- int64) {        defer n.Done()        for _, entry := range dirents(dir) {                if entry.IsDir() {                        n.Add(1)                        subdir := path.Join(dir, entry.Name())                        //開啟多個goroutine進行遞迴                        go walkDir(subdir, n, fileSizes)                } else {                        fileSizes <- entry.Size()                }        }}var sema = make(chan struct{}, 20)// dirents returns the entries of directory dir.func dirents(dir string) []os.FileInfo {        //使用計數訊號量邏輯限制太多並發        sema <- struct{}{}        entries, err := ioutil.ReadDir(dir)        <-sema        if err != nil {                fmt.Fprintf(os.Stderr, "du1: %v\n", err)                return nil        }        return entries}func printDiskUsage(nfiles, nbytes int64) {        fmt.Printf("%d files  %.1f GB\n", nfiles, float64(nbytes)/1e9)}

  

[日常] Go語言聖經-樣本: 並發的目錄遍曆習題

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.