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

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

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681131112758/5a731ca4-3bac-4e9e-aaec-e96697743348.png align="center")

舉個例子，假設我們有一個 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：

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681131097525/fb9cc0af-cd37-4220-8525-c52b445cb779.png align="center")

## 參考資料

* [Ubuntu Manpage: fcntl - manipulate file descriptor](https://manpages.ubuntu.com/manpages/impish/man2/fcntl.2.html)
    

> 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.
