我正在处理的应用程序需要使计数器的值在多个调用中保持不变,这样每次再次启动应用程序时,都会读回计数器的值并从那里继续计数。该值应以人类可读的形式存储,以便在需要时可以轻松检查,并且应该以原子方式更新,以便失败不会弄乱先前的持久值。
使用普通的旧文本文件似乎太无聊了,所以经过一些创造性的思考后,我发现我可以通过将计数器存储为符号链接目标来实现相同的目标。
基本上,使用sh作为原型语言,而不是使用
echo $counter > file.tmp && mv file.tmp file || rm -f file.tmp
我愿意
ln -s $counter file.tmp && mv file.tmp file || rm -f file.tmp
后一种方法的优点是我只需要一个系统调用来写入文件,而不是前一种情况下至少 3。
作为额外的好处,从shell中执行ls -l
会自动显示文件的内容:
$ ls -l the.counter.is
lrwxrwxrwx 1 fabio fabio 4 mar 7 01:08 the.counter.is -> 1234
关于性能的问题,在我的PC上执行比较两种方法(see it here)的测试程序,我得到的结果符合预期,符号链接方法比标准方法快7倍(注意该测试并不关心原子性):
$ uname -a && ./linkfile 10000 4095 /tmp/test
Linux Fabio-Asus 4.8.0-40-generic #43-Ubuntu SMP Thu Feb 23 16:01:19 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
Starting test... [10000, 4095]
writeToFile: 155.537ms
writeToLink: 23.4132ms
然而,on coliru我得到了不同的结果,略微支持标准方法:
uname -a && g++ -O3 -o test main.cpp && sync && ./test 10000 4095 x
Linux stacked-crooked 4.4.0-57-generic #78-Ubuntu SMP Fri Dec 9 23:50:32 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
Starting test... [10000, 4095]
writeToFile: 21.8001us
writeToLink: 33.9217us
每个方法的测试包含10000次迭代,每次迭代写入4095个字节,并平均执行时间。
4095字节的原因是导致symlink
系统调用因ENAMETOOLONG
而失败的原因。
所以问题是:
i7-6500U CPU @ 2.50GHz
,您是否知道为什么在coliru上标准方法比在我的电脑上快得多,两者都与符号链接方法并且在绝对时间内?如果是因为某些缓存,为什么那些也不会影响我的PC,为什么它们不会对符号链接方法产生积极影响?答案 0 :(得分:0)
我的回答:
flock
在NFS上不可靠并且使用了符号链接的情况。