做网站注册哪类商标,换服务器wordpress升级,wordpress qps,酒店营销策略案例
并发目录大小统计
业务逻辑
统计目录的文件数量和大小#xff08;或其他信息#xff09;。示例输出#xff1a; // 某个目录#xff1a;2637 files 1149.87 MB
实现思路 给定一个或多个目录#xff0c;并发的统计每个目录的size#xff0c;最后累加到一起。 当…案例
并发目录大小统计
业务逻辑
统计目录的文件数量和大小或其他信息。示例输出 // 某个目录2637 files 1149.87 MB
实现思路 给定一个或多个目录并发的统计每个目录的size最后累加到一起。 当目录中存在子目录时递归的统计。 每个目录的统计都由独立的Goroutine完成 累计总Size由独立的Goroutine完成 使用Channel传递获取的文件大小 使用WaitGroup调度
核心代码 // 读取目录内容// os.ReadDirfunc ReadDir(name string) ([]DirEntry, error)entries, err : os.ReadDir(dir)// 取得文件信息info, err : entry.Info()//判定是否为目录entry.IsDir()
编码实现 func WalkDir(dirs ...string) string {if len(dirs) 0 {dirs []string{.}}filesizeCh : make(chan int64, 1)wg : sync.WaitGroup{}for _, dir : range dirs {wg.Add(1)go walkDir(dir, filesizeCh, wg)}go func(wg *sync.WaitGroup) {wg.Wait()close(filesizeCh)}(wg)var fileNum, sizeTotal int64for filesize : range filesizeCh {fileNumsizeTotal filesize}return fmt.Sprintf(%d files %.2f MB\n, fileNum, float64(sizeTotal)/1e6)}func walkDir(dir string, fileSizes chan- int64, wg *sync.WaitGroup) {defer wg.Done()for _, fileinfo : range fileInfos(dir) {if fileinfo.IsDir() {subDir : filepath.Join(dir, fileinfo.Name())wg.Add(1)go walkDir(subDir, fileSizes, wg)} else {fileSizes - fileinfo.Size()}}}func fileInfos(dir string) []fs.FileInfo {entries, err : os.ReadDir(dir)if err ! nil {fmt.Fprintf(os.Stderr, walkdir: %v\n, err)return []fs.FileInfo{}}infos : make([]fs.FileInfo, 0, len(entries))for _, entry : range entries {info, err : entry.Info()if err ! nil {continue}infos append(infos, info)}return infos}
测试执行 go test -runWalkDir70 files 0.09 MBPASSok goConcurrency 0.321s
快速排序的并发编程实现
典型的单线程快速排序实现 func QuickSortSingle(arr []int) []int {// 确保arr中至少存在2个或以上元素if arr nil || len(arr) 2 {return arr}// 执行排序quickSortSingle(arr, 0, len(arr)-1)return arr}func quickSortSingle(arr []int, l, r int) {// 判定待排序范围是否合法if l r {// 获取参考元素位置索引mid : partition(arr, l, r)// 递归排序左边quickSortSingle(arr, l, mid-1)// 递归排序右边quickSortSingle(arr, mid1, r)}}// 大小分区返回参考元素索引func partition(arr []int, l, r int) int {p : l - 1for i : l; i r; i {if arr[i] arr[r] {pswap(arr, p, i)}}return p}// 交换arr中i和j元素func swap(arr []int, i, j int) {t : arr[i]arr[i] arr[j]arr[j] t}
并发编程实现思路 使用独立的Goroutine完成arr中某部分的排序 WaitGroup 完成等待阻塞同步
编码实现 // QuickSortConcurrency 快速排序调用函数func QuickSortConcurrency(arr []int) []int {// 一校验arr是否满足排序需要至少要有2个元素if arr nil || len(arr) 2 {return arr}// 四同步的控制wg : sync.WaitGroup{}// 二执行排序// 初始排序整体[0, len(arr)-1]wg.Add(1)go quickSortConcurrency(arr, 0, len(arr)-1, wg)wg.Wait()// 三返回结果return arr}// 实现递归快排的核心函数// 接收arr和排序区间的索引位置[l, r]func quickSortConcurrency(arr []int, l, r int, wg *sync.WaitGroup) {// 一-1wg的计数器defer wg.Done()// 二判定是否需要排序 l rif l r {// 三大小分区元素并获取参考元素索引mid : partition(arr, l, r)// 四并发对左部分排序wg.Add(1)go quickSortConcurrency(arr, l, mid-1, wg)// 五并发的对右部分排序wg.Add(1)go quickSortConcurrency(arr, mid1, r, wg)}}
partition 和 swap 部分不变。
测试执行 func TestQuickSortConcurrency(t *testing.T) {randArr : GenerateRandArr(1000)sortArr : QuickSortConcurrency(randArr)fmt.Println(sortArr)}// 生成大的随机数组func GenerateRandArr(l int) []int {// 生产大量的随机数arr : make([]int, l)rand.Seed(time.Now().UnixMilli())for i : 0; i l; i {arr[i] int(rand.Int31n(int32(l * 5)))}return arr} go test -runQuickSortConcurrency