fcntl()
的 POSIX 规范指出:
当该进程关闭该文件的文件描述符或持有该文件描述符的进程终止时,与给定进程的文件关联的所有锁都应被删除。
解锁已终止进程所持有的文件段锁的操作是否是每个文件的原子操作?换句话说,如果一个进程锁定了文件的字节段 B1..B2 和 B3..B4,但在终止之前没有解锁这些段,则当系统开始解锁它们时,将是段 B1..B2 和 B3。 .B4 在另一个锁定文件段的fcntl()
操作之前解锁可以成功吗?如果不是每个文件的原子性,系统解锁这些文件段的顺序是否取决于最初获取文件段的顺序?
fcntl() 的规范没有说明,但 POSIX 规范中可能有一个一般规定,要求在进程不正常退出或崩溃后进行清理操作的确定性顺序。
The POSIX specification for fcntl()
states:
All locks associated with a file for a given process shall be removed when a file descriptor for that file is closed by that process or the process holding that file descriptor terminates.
Is this operation of unlocking the file segment locks that were held by a terminated process atomic per-file? In other words, if a process had locked byte segments B1..B2 and B3..B4 of a file but did not unlock the segments before terminating, when the system gets around to unlocking them, are segments B1..B2 and B3..B4 both unlocked before another fcntl()
operation to lock a segment of the file can succeed? If not atomic per-file, does the order in which these file segments are unlocked by the system depend on the order in which the file segments were originally acquired?
The specification for fcntl()
does not say, but perhaps there is a general provision in the POSIX specification that mandates a deterministic order on operations to clean up after a process that exits uncleanly or crashes.
发布评论
评论(2)
第 2.9.7 节“线程交互”中有部分答案使用 POSIX 规范的常规文件操作:
因此,对于常规文件,如果进程的线程持有文件段上的锁,并在与该文件关联的最后一个文件描述符上调用 close() ,则 close 的效果()(包括删除进程持有的文件上所有未完成的锁)相对于另一个进程的线程调用
fcntl()
的效果而言是原子的锁定文件的一部分。exit()
的规范指出:大概,打开的文件描述符被关闭就像通过适当的调用
close()
,但不幸的是规范没有说明打开的文件描述符如何“关闭”。当涉及异常进程终止的步骤时,2004 年规范似乎更加模糊。我唯一能找到的是
abort()
。至少在 2008 年规范中,有一个标题为 进程终止的后果 在
_Exit()
页面上。不过,措辞仍然是:更新:我刚刚在 Austin Group 缺陷跟踪器中打开问题 0000498。
There's a partial answer in section 2.9.7, Thread Interactions with Regular File Operations, of the POSIX specification:
So, for a regular file, if a thread of a process holds locks on segments of a file and calls
close()
on the last file descriptor associated with the file, then the effects ofclose()
(including removing all outstanding locks on the file that are held by the process) are atomic with respect to the effects of a call tofcntl()
by a thread of another process to lock a segment of the file.The specification for
exit()
states:Presumably, open file descriptors are closed as if by appropriate calls to
close()
, but unfortunately the specification does not say how open file descriptors are "closed".The 2004 specification seems even more vague when it comes to the steps of abnormal process termination. The only thing I could find is the documentation for
abort()
. At least with the 2008 specification, there is a section titled Consequences of Process Termination on the page for_Exit()
. The wording, though, is still:UPDATE: I just opened issue 0000498 in the Austin Group Defect Tracker.
我不认为 POSIX 规范规定锁的释放是否是原子的,所以你应该假设它的行为对你来说尽可能不方便。如果你需要它们是原子的,它们就不是;如果您需要单独处理它们,它们是原子的;如果你不在乎,有些机器会以一种方式做,而另一些机器会以另一种方式做。所以,编写你的代码,这样就无关紧要了。
我不确定您如何编写代码来检测问题。
在实践中,我希望锁会被原子释放,但标准没有说明,所以你不应该假设。
I don't think the POSIX specification stipulates whether the releasing of locks is atomic or not, so you should assume that it behaves as inconveniently as possible for you. If you need them to be atomic, they aren't; if you need them to be handled separately, they're atomic; if you don't care, some machines will do it one way and other machines the other way. So, write your code so that it doesn't matter.
I'm not sure how you'd write code to detect the problem.
In practice, I expect that the locks would be released atomically, but the standard doesn't say, so you should not assume.