2013-03-01 59 views
0

我正在使用tmpnam()在進程1中生成臨時文件名。 打開該文件並將文件名發送到另一進程2. 另一個進程2打開並且寫入該文件。內核是否在進程死亡時刪除打開的文件

但是,只是我想知道我的進程1是否會死掉,該文件是否會被操作系統刪除。看起來不像是這樣。在那種情況下,我的選擇是什麼,以便在進程1死後我沒有任何文件。

回答

0

不,內核在您的進程死亡時不會刪除打開的文件。

但是,您可以在進程死亡之前刪除打開的文件,只要保持打開文件,文件仍然會存在。但是,您將不能再通過名稱打開文件- 只能通過打開的文件句柄進行進一步的訪問。

例如

fname="/tmp/tempfilename"; 
fd=open(fname,O_RDWR); 
unlink(fname); 
/* fd is still a valid handle that can be written to, read from, 
    lseeked on, or passed to a child process. It will go away 
    when the process exits. 
*/ 
/* Important note: if you create a temp file like this on a 
    NFS filesystem, there will be a phantom file named something like 
    .nfsfile12983719 
    that will stick around until the file descriptor is closed. 
    If you delete this file, it will be re-created. 
    */ 

或者,你可以使用tmpfile(3)其大致做同樣的事情,除了 返回FILE *而非FD它。

+0

謝謝你的回覆! 我正在使用該文件在這兩個進程之間傳遞信息。所以,我不能在創建它之後立即從流程1中取消鏈接文件,因爲流程2不會寫入它。 我不能使用tmpfile(),因爲那不會給我一個文件名來傳遞給其他進程。它只是直接給我流。 然後,我使用atexit()函數在退出時取消鏈接文件。它現在適用於正確的流程退出。但是,對於崩潰,仍然不好。 我想我只需要安裝更多的信號處理程序。 – user2125280 2013-03-02 00:54:49

+0

有兩種方法可以將打開的fd直接傳遞給另一個進程。最簡單的方法是使用fork/exec:打開的fds不會關閉(除非它們專門設置爲這樣)。另一種方式是使用unix域套接字和sendmsg;詳情請參閱man 3 cmsg。你可以做的另一件事是簡單地設置一個cronjob,刪除任何不再使用的臨時文件。爲每個信號設置信號處理程序可能有問題且不可靠。 – 2013-03-04 17:22:12

0

操作系統不會爲您刪除文件。確定意圖會很棘手:是用一些有用的數據寫出來的文件,還是現在流程已經消失的文件。

有幾種方法可以考慮處理這個問題。在典型情況下,您可以作爲退出的一部分進行清理。 如果您遇到問題,您幾乎總能得到一個信號,您可以使用它來清理問題。這裏有一個例子:Basic Signal Handling我拿這個例子。

#include <signal.h> 

void 
termination_handler (int signum) 
{ 
    struct temp_file *p; 

    for (p = temp_file_list; p; p = p->next) 
    unlink (p->name); 
} 

int 
main (void) 
{ 
    ... 
    if (signal (SIGINT, termination_handler) == SIG_IGN) 
    signal (SIGINT, SIG_IGN); 
    if (signal (SIGHUP, termination_handler) == SIG_IGN) 
    signal (SIGHUP, SIG_IGN); 
    if (signal (SIGTERM, termination_handler) == SIG_IGN) 
    signal (SIGTERM, SIG_IGN); 
    ... 
} 

另一種方法是在文件名(或文件內容)中嵌入pid。如果你的程序啓動並看到一個與你的程序正在運行的實例不匹配的pid文件,你可以嘗試清理它。這似乎有點危險。

另外一個稍微有點臭的解決方法是將它放在/ tmp /中,它可以清理乾淨,如果它被刪除,則以某種方式處理它。

+0

我的文件實際上位於/ tmp /目錄中。但是,除非我的流程刪除它,否則它將如何清理?我在這裏錯過了一些東西。對於正確的終止, – user2125280 2013-03-02 01:16:27

+0

atexit()是有用的。但是,考慮到一個進程可能由於各種原因而終止,安裝所有信號的處理程序來關閉該進程的打開文件似乎有點不合理。我仍然在看.. – user2125280 2013-03-02 01:20:25