17

2020-12-11:多个线程同时写同一个日志文件,为什么相互写的内容不会被覆盖?

 3 years ago
source link: https://studygolang.com/articles/32117
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

福哥答案2020-12-11:

答案来自此链接:

这是道面试题,可惜我没什么思路,网上找了些答案。如果有更好的答案,请直接评论。

1.没看代码前,以为会用到缓存队列+组提交。

2.golang的日志源码位于log/log.go中的Output方法。加锁了。

3.系统级别。当打开文件并设置了O_APPEND标识,内核会共享文件写入游标,保证内容不会被覆盖。

这个问题涉及到 系统底层 ,这就要看 操作 系统, 与 Windows 不同, Linux 允许一个文件在写入的时候被读取(或者在被读取的时候写入)。

Linux 通过文件描述符表维护了打开的文件描述符信息,而文件描述符表中的每一项都指向一个内核维护的文件表,文件表指向打开的文件的 vnode(Unix) 和 inode。同时,文件表保存了进程对文件读写的偏移量等信息。

但是 那么我们要如何保证读取与写入的一致性呢? Linux 提供了 fcntl 系统调用,可以锁定文件。

文件锁是与进程相关的,一个进程中的多个线程/协程对同一个文件进行的锁操作会互相覆盖掉,从而无效。

fcntl 创建的锁是建议性锁,只有写入的进程和读取的进程都遵循建议才有效;对应的有强制性锁,会在每次文件操作时进行判断,但性能较差,因此 Linux/Unix 系统默认采用的是建议性锁。

评论

有疑问加站长微信联系(非本文作者)

eUjI7rn.png!mobile

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK