我對該功能的作業程序感到困惑mkstemp()。
在該函式的man頁面中mkstemp,據說該函式生成唯一名稱并創建具有該名稱的檔案。
我認為有可能當在mkstemp()目錄中檢查該檔案名并在實際創建該檔案之前發現它是唯一的時,另一個程式可以創建具有完全相同名稱的檔案(雖然機會非常低,但理論上是可能的) . 盡管它使用O_EXCL標志將無法創建檔案。因此,它必須再次檢查新檔案名并創建它。這是實際的程序mkstemp()嗎?
所以,我認為檢查檔案名和實際創建檔案,都不是原子地處理它。(我可能錯了)
使用POSIX系統
uj5u.com熱心網友回復:
mkstemp() 實際上是如何作業的?
源代碼是演算法的文字描述。進行一項實施并對其進行檢查。
https://github.com/lattera/glibc/blob/master/misc/mkstemp.c -> https://github.com/lattera/glibc/blob/master/sysdeps/posix/tempname.c
- https://github.com/lattera/glibc/blob/master/sysdeps/posix/tempname.c檢查輸入
- https://github.com/lattera/glibc/blob/master/sysdeps/posix/tempname.c#L229獲取一些隨機資料
- https://github.com/lattera/glibc/blob/master/sysdeps/posix/tempname.c#L241重復https://github.com/lattera/glibc/blob/master/sysdeps/posix/tempname.c #L211指定嘗試次數
- https://github.com/lattera/glibc/blob/master/sysdeps/posix/tempname.c#L245
XXXXXX用亂數填充 - https://github.com/lattera/glibc/blob/master/sysdeps/posix/tempname.c#L261打開檔案
O_CREAT | O_EXCL- https://github.com/lattera/glibc/blob/master/sysdeps/posix/tempname.c#L293如果檔案打開回傳,如果未知錯誤回傳,如果檔案存在,重復
- https://github.com/lattera/glibc/blob/master/sysdeps/posix/tempname.c#L245
所以沒有“檢查”,檔案是從一開始就打開的O_CREAT | O_EXCL,所以創建和檢查是一起完成的。有關標志的說明,請參見https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html 。open
uj5u.com熱心網友回復:
(雖然幾率很低,但理論上是可能的)
不,這是不可能的(甚至理論上),因為用于創建檔案的open()系統呼叫mkstemp()保證沒有兩個行程可以同時創建相同的O_CREAT檔案O_EXCL。當內核創建檔案時,目錄 inode 被鎖定(因此,不允許同時在該目錄中創建任何其他檔案),這保證了兩個open()s 將被序列化(一個首先,或者另一個,但不是同時同時)這意味著當第二個行程有機會創建檔案時,open()呼叫失敗,因為該檔案已由其他行程創建。為了盡量減少這種情況,該函式通常使用行程的 pid 作為名稱的一部分,因此兩個行程不能同時生成相同的檔案名,因為它們具有不同的行程 id)mkstemp()可能會使用不同的名稱重試系統呼叫,或者只是失敗。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/413766.html
標籤:
上一篇:fork()在這里做什么?
