我正在使用tmpnam()在進程1中生成臨時文件名。 打開該文件並將文件名發送到另一進程2. 另一個進程2打開並且寫入該文件。內核是否在進程死亡時刪除打開的文件
但是,只是我想知道我的進程1是否會死掉,該文件是否會被操作系統刪除。看起來不像是這樣。在那種情況下,我的選擇是什麼,以便在進程1死後我沒有任何文件。
我正在使用tmpnam()在進程1中生成臨時文件名。 打開該文件並將文件名發送到另一進程2. 另一個進程2打開並且寫入該文件。內核是否在進程死亡時刪除打開的文件
但是,只是我想知道我的進程1是否會死掉,該文件是否會被操作系統刪除。看起來不像是這樣。在那種情況下,我的選擇是什麼,以便在進程1死後我沒有任何文件。
不,內核在您的進程死亡時不會刪除打開的文件。
但是,您可以在進程死亡之前刪除打開的文件,只要保持打開文件,文件仍然會存在。但是,您將不能再通過名稱打開文件- 只能通過打開的文件句柄進行進一步的訪問。
例如
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它。
操作系統不會爲您刪除文件。確定意圖會很棘手:是用一些有用的數據寫出來的文件,還是現在流程已經消失的文件。
有幾種方法可以考慮處理這個問題。在典型情況下,您可以作爲退出的一部分進行清理。 如果您遇到問題,您幾乎總能得到一個信號,您可以使用它來清理問題。這裏有一個例子: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 /中,它可以清理乾淨,如果它被刪除,則以某種方式處理它。
我的文件實際上位於/ tmp /目錄中。但是,除非我的流程刪除它,否則它將如何清理?我在這裏錯過了一些東西。對於正確的終止, – user2125280 2013-03-02 01:16:27
atexit()是有用的。但是,考慮到一個進程可能由於各種原因而終止,安裝所有信號的處理程序來關閉該進程的打開文件似乎有點不合理。我仍然在看.. – user2125280 2013-03-02 01:20:25
謝謝你的回覆! 我正在使用該文件在這兩個進程之間傳遞信息。所以,我不能在創建它之後立即從流程1中取消鏈接文件,因爲流程2不會寫入它。 我不能使用tmpfile(),因爲那不會給我一個文件名來傳遞給其他進程。它只是直接給我流。 然後,我使用atexit()函數在退出時取消鏈接文件。它現在適用於正確的流程退出。但是,對於崩潰,仍然不好。 我想我只需要安裝更多的信號處理程序。 – user2125280 2013-03-02 00:54:49
有兩種方法可以將打開的fd直接傳遞給另一個進程。最簡單的方法是使用fork/exec:打開的fds不會關閉(除非它們專門設置爲這樣)。另一種方式是使用unix域套接字和sendmsg;詳情請參閱man 3 cmsg。你可以做的另一件事是簡單地設置一個cronjob,刪除任何不再使用的臨時文件。爲每個信號設置信號處理程序可能有問題且不可靠。 – 2013-03-04 17:22:12