#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微秒,但最后一个链接几乎是十分之二秒才能执行.