新闻详情

新闻详情

首页 / 资讯中心 / 详情

c实现fastdu替代du -sh ./* -c命令

发布时间:2026/9/29 21:23:44来源:尧图网络
c实现fastdu替代du -sh ./* -c命令
编辑命令gcc -O2 -pthread -stdc11 -o fastdu fastdu.c运行命令./fastdu # 用当前系统 CPU 核数个线程./fastdu -j 16 # 手动指定 16 线程#define _GNU_SOURCE #include stdio.h #include stdlib.h #include string.h #include dirent.h #include sys/stat.h #include unistd.h #include pthread.h typedef struct { char *path; int root; } task_t; static struct { task_t *buf; int cap, head, count; int active; /* 已弹出但未完成的任务数 */ pthread_mutex_t mtx; pthread_cond_t cond; } Q; static long long *root_sizes; static void queue_init(int cap) { Q.cap cap 0 ? cap : 64; Q.buf malloc(sizeof(task_t) * Q.cap); Q.head Q.count Q.active 0; pthread_mutex_init(Q.mtx, NULL); pthread_cond_init(Q.cond, NULL); } /* 取任务返回 0 表示全部完成 */ static int queue_pop(task_t *out) { pthread_mutex_lock(Q.mtx); while (Q.head Q.count Q.active 0) pthread_cond_wait(Q.cond, Q.mtx); if (Q.head Q.count) { pthread_mutex_unlock(Q.mtx); return 0; } *out Q.buf[Q.head]; if (Q.head Q.count) Q.head Q.count 0; /* 顺带回收数组头部 */ Q.active; pthread_mutex_unlock(Q.mtx); return 1; } static void queue_push(char *path, int root) { /* 接管 path 所有权 */ pthread_mutex_lock(Q.mtx); if (Q.count Q.cap) { if (Q.head 0) { /* 先压缩再扩容 */ int n Q.count - Q.head; memmove(Q.buf, Q.buf Q.head, sizeof(task_t) * n); Q.head 0; Q.count n; } if (Q.count Q.cap) { Q.cap * 2; Q.buf realloc(Q.buf, sizeof(task_t) * Q.cap); } } Q.buf[Q.count].path path; Q.buf[Q.count].root root; Q.count; pthread_cond_signal(Q.cond); pthread_mutex_unlock(Q.mtx); } static void queue_done(void) { pthread_mutex_lock(Q.mtx); Q.active--; if (Q.active 0 Q.head Q.count) pthread_cond_broadcast(Q.cond); pthread_mutex_unlock(Q.mtx); } static inline void add_size(int root, long long sz) { __atomic_fetch_add(root_sizes[root], sz, __ATOMIC_RELAXED); } static void *worker(void *arg) { (void)arg; task_t t; while (queue_pop(t)) { DIR *d opendir(t.path); if (d) { size_t plen strlen(t.path); struct dirent *e; while ((e readdir(d)) ! NULL) { const char *n e-d_name; if (n[0] . (n[1] \0 || (n[1] . n[2] \0))) continue; /* 跳过 . 和 .. */ size_t nlen strlen(n); char *full malloc(plen nlen 2); memcpy(full, t.path, plen); full[plen] /; memcpy(full plen 1, n, nlen 1); if (e-d_type DT_DIR) { queue_push(full, t.root); } else if (e-d_type DT_REG) { struct stat st; if (stat(full, st) 0) add_size(t.root, st.st_size); free(full); } else if (e-d_type DT_UNKNOWN) { struct stat st; /* 某些文件系统 d_type 无效 */ if (lstat(full, st) 0) { if (S_ISDIR(st.st_mode)) queue_push(full, t.root); else { add_size(t.root, st.st_size); free(full); } } else free(full); } else { free(full); /* 符号链接/fifo 等直接忽略 */ } } closedir(d); } free(t.path); queue_done(); } return NULL; } static void fmt_size(long long sz, char *buf, size_t buflen) { static const char *u[] {, K, M, G, T, P}; double v (double)sz; int i 0; while (v 1024.0 i 5) { v / 1024.0; i; } if (i 0) snprintf(buf, buflen, %lld, sz); else if (v 10.0) snprintf(buf, buflen, %.1f%s, v, u[i]); else snprintf(buf, buflen, %.0f%s, v, u[i]); } static int cmp_str(const void *a, const void *b) { return strcmp(*(char * const *)a, *(char * const *)b); } int main(int argc, char **argv) { int nthreads 0, opt; while ((opt getopt(argc, argv, j:)) ! -1) if (opt j) nthreads atoi(optarg); if (nthreads 0) { long n sysconf(_SC_NPROCESSORS_ONLN); nthreads (n 0) ? (int)n : 4; } if (nthreads 64) nthreads 64; DIR *d opendir(.); if (!d) { perror(opendir); return 1; } char **names NULL; int nn 0, cap 0; struct dirent *e; while ((e readdir(d)) ! NULL) { if (e-d_name[0] .) continue; /* 与 ./* 通配一致 */ if (cap nn) { cap cap ? cap * 2 : 64; names realloc(names, sizeof(char *) * cap); } names[nn] strdup(e-d_name); } closedir(d); qsort(names, nn, sizeof(char *), cmp_str); root_sizes calloc(nn 0 ? nn : 1, sizeof(long long)); queue_init(nn 0 ? nn : 64); for (int i 0; i nn; i) { size_t l strlen(names[i]) 3; char *p malloc(l); snprintf(p, l, ./%s, names[i]); struct stat st; if (lstat(p, st) 0) { if (S_ISDIR(st.st_mode)) { queue_push(p, i); continue; } add_size(i, st.st_size); /* 顶层普通文件 */ } free(p); } pthread_t *th malloc(sizeof(pthread_t) * nthreads); for (int i 0; i nthreads; i) pthread_create(th[i], NULL, worker, NULL); for (int i 0; i nthreads; i) pthread_join(th[i], NULL); long long total 0; char buf[32]; for (int i 0; i nn; i) { fmt_size(root_sizes[i], buf, sizeof buf); printf(%8s ./%s\n, buf, names[i]); total root_sizes[i]; } fmt_size(total, buf, sizeof buf); printf(%8s total\n, buf); return 0; }
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Markdown 编辑器选型与高效写作工作流:从语法到导出的完整指南 2026/9/29 22:18:00

Markdown 编辑器选型与高效写作工作流:从语法到导出的完整指南

如果用一句话概括我这几年写东西的习惯,那就是:能 Markdown 就绝不用 Word。方案、周报、读书笔记、公众号草稿、技术文档,甚至毕业论文的初稿,我都是在 Markdown 编辑器里写完,再按需导出成 PDF 或 Word。最开始只是嫌…

阅读更多 →
共享凭据紧急熔断与一键夺权:企业密码管理器(安当SYP)在突发安全事件中的秒级冻结实践 2026/9/29 22:18:00

共享凭据紧急熔断与一键夺权:企业密码管理器(安当SYP)在突发安全事件中的秒级冻结实践

一、为什么特权共享凭据必须能"秒级熔断" 在很多企业的真实环境里,"共享账号"不是例外,而是常态。财务共用一个网银操作员号,供应链审核组共用一个采购平台账号,车企研发外包团队共用一台跳板机的域账号&…

阅读更多 →
自然语言驱动Blender建模,Antigravity+MCP快速构建智慧仓储数字孪生场景 2026/9/29 22:17:59

自然语言驱动Blender建模,Antigravity+MCP快速构建智慧仓储数字孪生场景

先说个可能有点反直觉的结论:一套看起来很唬人的智慧仓储数字孪生场景,最耗时间的往往不是渲染,不是动画,而是最基础的那批3D资产建模和场景装配。传统做法里,建模师照着平面图一点点拉墙、摆货架、布库位,…

阅读更多 →
牛客笔试会录屏吗?判定吃的是每 30 到 40 秒一张的截图 2026/9/29 22:17:26

牛客笔试会录屏吗?判定吃的是每 30 到 40 秒一张的截图

先交代位置。我们在做面试和笔试的实时辅助工具,这两年拆了不少考试端的前端和客户端,也一直在拿各家助手那句「完全隐身」去对照实测。下面写的是拆出来和查到的结果,落点只有一个:对方那一侧到底在采什么。 这篇讲在线笔试&…

阅读更多 →
国产codex技术研发进展与应用场景全景解析 2026/9/29 22:17:20

国产codex技术研发进展与应用场景全景解析

科研路上最浪费时间的不是实验失败,而是“工具焦虑”——下载一堆软件,用到一半弃坑,效率反而更低。这篇只挑4款真正高频、互补的工具,第一个重磅拆解切问学术(文献全链路救星),其余三款覆盖管理…

阅读更多 →
179、MLIR的Profiling(性能分析)与Timing(计时)Pass 2026/9/29 22:17:20

179、MLIR的Profiling(性能分析)与Timing(计时)Pass

MLIR的Profiling(性能分析)与Timing(计时)Pass 上周帮团队调一个AI推理引擎的算子性能问题,模型跑在自研NPU上,某个卷积算子的延迟比预期高了3倍。常规手段——插桩、打印时间戳、甚至用perf去抓——都试了,结果发现瓶颈不在计算本身,而在MLIR编译后的IR调度上。那个调…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉