4

状态的POSIX 规范fcntl()

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

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

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

4

2 回答 2

2

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

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

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

状态规范exit()

这些函数将终止调用进程,结果如下:

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

  • ...

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

2004 年的规范对于异常进程终止的步骤似乎更加模糊。我唯一能找到的是abort(). 至少在 2008 年的规范中,页面上有一个标题为“进程终止的后果”_Exit()的部分。但是,措辞仍然是:

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

更新:我刚刚在 Austin Group Defect Tracker 中打开了问题 0000498

于 2011-10-01T23:20:12.347 回答
1

我不认为 POSIX 规范规定释放锁是否是原子的,所以你应该假设它对你来说尽可能不方便。如果您需要它们是原子的,它们不是;如果您需要单独处理它们,它们是原子的;如果您不在乎,有些机器会以一种方式进行,而另一些机器会以另一种方式进行。所以,写你的代码,这样它就无关紧要了。

我不确定您将如何编写代码来检测问题。

在实践中,我希望锁会被原子释放,但标准并没有说,所以你不应该假设。

于 2011-10-01T22:18:33.890 回答