Linux fcntl Filelock 中的小坑:在同一 Process 不能跨 Thread 使用

·

1 min read

在 Linux 系統下,我們可以透過 fcntl 來提供跨 Process 的 Read/Write Filelock,但是卻有一個小小的坑需要注意,那就是在同一個 Process 內,不可以跨 Thread 使用這個 Lock。

舉個例子,假設我們有一個 Process A,會定期地更新 /srv/mydata 這個資料夾,當更新時,會去使用 WLock /srv/mydata.lock 來鎖住該資料夾。另一方面,Process B 的 Thread 1 則需要讀取 /srv/mydata/data1,因此也需要進行 RLock /srv/mydata.lock 的動作。

但是,如果在 Process B 中,還有一個 Thread 2 需要讀取 /srv/mydata/data2,那麼該 Thread 2 便不能再去 RLock /srv/mydata.lock,因為這個 fcntl 的 Lock 是 Per process 的,如果 Thread 1 和 Thread 2 同時進行 RLock,當其中一個 Thread 進行 UnRlock 後,整個 Process 就不再 Own 這個 Filelock。

也就是說如果某個 Thread 關閉了該檔案的任何 file descriptor,那麼這個 Process 所擁有的所有 Lock 都會被釋放,不論這些 Lock 是使用哪些 file descriptor 取得的。因此,在使用 fcntl 進行 Filelock 時,要特別留意各個 Process 和 Thread 之間的關係,避免出現意外的競爭情況。

解法可能是分拆兩個 Lock:

參考資料

If a process closes any file descriptor referring to a file, then all of the process's locks on that file are released, regardless of the file descriptor(s) on which the locks were obtained.