C语言 POSIX系统清除未完全解锁的文件锁的顺序是什么?



fcntl()状态的POSIX规范:

当该文件的文件描述符被该进程关闭或持有该文件描述符的进程终止时,与该文件关联的所有锁将被移除。

这个操作是释放被终止进程持有的文件段锁吗?换句话说,如果一个进程锁定了字节段B1..B2和B3..一个文件的B4,但在终止之前没有解锁这些段,当系统开始解锁它们时,它们是段B1..B2和B3..B4都解锁之前,另一个fcntl()操作锁定文件段可以成功吗?如果不是每个文件原子,那么系统解锁这些文件段的顺序是否取决于文件段最初被获取的顺序?

fcntl()的规范没有说,但可能在POSIX规范中有一个一般规定,要求在进程不干净地退出或崩溃后对操作进行清理的确定性顺序。

在POSIX规范的第2.9.7节,线程与常规文件操作的交互中有部分答案:

所有的函数chmod(), close(), fchmod(), fcntl(), fstat(), lseek(), open(), read(), readlink(), stat(), symlink()和write()在操作常规文件时,在IEEE Std 1003.1-2001中规定的效果中,它们之间应该是原子的。如果两个线程各自调用其中一个函数,则每个调用要么看到另一个调用的所有指定效果,要么看不到任何指定效果。

因此,对于一个常规文件,如果一个进程的线程持有文件段上的锁,并在与该文件关联的最后一个文件描述符上调用close(),那么close()的效果(包括删除进程持有的文件上所有未完成的锁)相对于另一个进程的线程调用fcntl()来锁定文件段的效果来说是原子的。

exit()状态规范:

这些函数将终止调用进程,并产生以下结果:

  • 在调用过程中打开的所有文件描述符、目录流[、转换描述符和消息目录描述符]应被关闭。

  • ……

可以推测,打开的文件描述符被关闭,就像通过适当调用close()来关闭一样,但不幸的是,规范没有说明如何"关闭"打开的文件描述符。

当涉及到异常进程终止的步骤时,2004规范似乎更加模糊。我唯一能找到的是abort()的文档。至少在2008年的规范中,_Exit()页面上有一个名为"进程终止的后果"的章节。不过,措辞仍然是:
  • 所有在调用过程中打开的文件描述符、目录流、转换描述符和消息目录描述符将被关闭。

更新:我刚刚在Austin Group缺陷跟踪器中打开了0000498问题。

我认为POSIX规范没有规定锁的释放是否是原子的,所以您应该假设它的行为对您来说尽可能不方便。如果你需要它们是原子的,它们不是;如果你需要分别处理它们,它们是原子的;如果你不在乎,有些机器会这样做,有些机器会那样做。所以,写你的代码,使它不重要。

我不确定你会如何编写代码来检测这个问题。

在实践中,我期望锁会自动释放,但是标准没有说,所以您不应该假设。

相关内容

  • 没有找到相关文章

最新更新