#include <unistd.h> #include <stdio.h> void dump_log(int size){ char cmd[1024]; snprintf(cmd, sizeof(cmd)/sizeof(cmd[0]), "dd if=/dev/zero of=from.bin bs=1024 count=%d", size); int ret = system(cmd); if (ret<0){ perror("system"); } } int main(){ const char *filepath = "from.bin"; while(1){ dump_log(1024*100); sleep(10); unlink(filepath); } return 0; }
strace -T ./a.out
显示:
unlink("from.bin") = 0 <0.019916>
取消链接文件(100M)花费19ms,解除链接文件时会发生什么? 为什么这么慢?
系统信息:linux 3.13.0-57-generic,Ubuntu 14.04.2 LTS,ext4
如果你有一个巨大的文件取消链接(2)内核不解锁inode,直到所有块指针返回到空闲块列表。 您可以通过制作第二个链接来检查时间上的差异(这将使得取消链接仅用于释放您正在删除的链接,而不会释放任何块)。 通过规范,释放所有这些块的代码就是你的进程(好吧,运行在内核模式下,而不是用户模式,但没有保留的进程将块返回到空闲列表),它将不会返回,直到它释放所有的块。
以下代码将说明这一点:
#include <errno.h> #include <getopt.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define D(X) "%s:%d:%s: " X, __FILE__, __LINE__, __func__ int main(int argc, char **argv) { int opt, i; while ((opt = getopt(argc, argv, "")) != EOF) { switch (opt) { } /* switch */ } /* while */ argc -= optind; argv += optind; for (i = 0; i < argc; i++) { struct timespec now, then; int res; res = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now); if (res < 0) { fprintf(stderr, D("ERROR: %s (errno = %d)\n"), strerror(errno), errno); exit(EXIT_FAILURE); } /* if */ unlink(argv[i]); res = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &then); if (res < 0) { fprintf(stderr, D("ERROR: %s (errno = %d)\n"), strerror(errno), errno); exit(EXIT_FAILURE); } /* if */ then.tv_nsec -= now.tv_nsec; then.tv_sec -= now.tv_sec; if (then.tv_nsec < 0) { then.tv_nsec += 1000000000L; then.tv_sec--; } /* if */ printf(D("%s: %d.%09d s. (CPU time)\n"), argv[i], then.tv_sec, then.tv_nsec); } /* for */ exit(EXIT_SUCCESS); } /* main */
然后我用这个命令构建一个2Gb文件:
$ yes | dd of=pepe bs=1M iflag=fullblock count=2048
然后我做了32个链接到这个文件:
i=0 while [ "$i" -lt 32 ] do ln pepe pepe$i i=$(expr $i + 1) done
然后我运行以下命令(仅显示CPU时间):
$ unlink pepe[0-9]* pepe unlink.c:47:main: pepe0: 0.000074272 s. (CPU time) unlink.c:47:main: pepe1: 0.000022722 s. (CPU time) unlink.c:47:main: pepe10: 0.000015034 s. (CPU time) unlink.c:47:main: pepe11: 0.000013254 s. (CPU time) unlink.c:47:main: pepe12: 0.000012827 s. (CPU time) unlink.c:47:main: pepe13: 0.000012462 s. (CPU time) unlink.c:47:main: pepe14: 0.000012241 s. (CPU time) unlink.c:47:main: pepe15: 0.000012753 s. (CPU time) unlink.c:47:main: pepe16: 0.000012517 s. (CPU time) unlink.c:47:main: pepe17: 0.000012245 s. (CPU time) unlink.c:47:main: pepe18: 0.000013104 s. (CPU time) unlink.c:47:main: pepe19: 0.000012491 s. (CPU time) unlink.c:47:main: pepe2: 0.000012662 s. (CPU time) unlink.c:47:main: pepe20: 0.000012606 s. (CPU time) unlink.c:47:main: pepe21: 0.000012803 s. (CPU time) unlink.c:47:main: pepe22: 0.000012597 s. (CPU time) unlink.c:47:main: pepe23: 0.000012391 s. (CPU time) unlink.c:47:main: pepe24: 0.000012582 s. (CPU time) unlink.c:47:main: pepe25: 0.000012557 s. (CPU time) unlink.c:47:main: pepe26: 0.000012386 s. (CPU time) unlink.c:47:main: pepe27: 0.000012261 s. (CPU time) unlink.c:47:main: pepe28: 0.000012245 s. (CPU time) unlink.c:47:main: pepe29: 0.000012351 s. (CPU time) unlink.c:47:main: pepe3: 0.000011940 s. (CPU time) unlink.c:47:main: pepe30: 0.000013003 s. (CPU time) unlink.c:47:main: pepe31: 0.000012231 s. (CPU time) unlink.c:47:main: pepe4: 0.000012777 s. (CPU time) unlink.c:47:main: pepe5: 0.000012546 s. (CPU time) unlink.c:47:main: pepe6: 0.000012461 s. (CPU time) unlink.c:47:main: pepe7: 0.000013129 s. (CPU time) unlink.c:47:main: pepe8: 0.000012311 s. (CPU time) unlink.c:47:main: pepe9: 0.000012446 s. (CPU time) unlink.c:47:main: pepe: 0.195457587 s. (CPU time)
正如你所看到的,除了最后一个环节外,大约需要12微秒,但最后几乎是十分之二秒。