Что произойдет, если процесс А читает файл, а процесс Б пытается его удалить?

«Что произойдет, если процесс А читает файл, а процесс Б пытается его удалить?» — вопрос из категории Linux и ОС, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Linux и других Unix-подобных системах файловая подсистема отделяет запись в каталоге (имя файла) от самих данных на диске (inode). Когда процесс открывает файл, ядро увеличивает счетчик ссылок для соответствующего inode.

Поведение:

  1. Процесс Б успешно выполняет системный вызов unlink("file.txt").
  2. Имя файла (file.txt) немедленно удаляется из каталога. Команда ls его больше не покажет.
  3. Однако, если процесс А уже открыл этот файл (имеет открытый файловый дескриптор), данные на диске не уничтожаются. Inode и блоки данных остаются доступными для процесса А через его дескриптор.
  4. Файл будет окончательно удален с диска, только когда процесс А закроет файл (и счетчик ссылок на inode станет равен 0).

Пример на C++ (системные вызовы POSIX):

// Процесс А (читатель)
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include <cstring>

int main() {
    int fd = open("testfile.txt", O_RDONLY);
    if (fd == -1) { /* обработка ошибки */ }

    char buffer[256];
    ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
    std::cout << "Прочитано: " << bytes_read << " байт. Файл открыт.n";

    // В этот момент другой процесс может выполнить unlink("testfile.txt")
    // Файл "исчез" из директории, но мы можем продолжать чтение.
    lseek(fd, 0, SEEK_SET); // Вернуться к началу файла
    bytes_read = read(fd, buffer, sizeof(buffer)); // Чтение все еще работает!

    sleep(10); // Имитация долгой работы с файлом
    close(fd); // ТЕПЕРЬ данные файла могут быть физически удалены с диска.
    return 0;
}

Ключевой момент: Это поведение позволяет выполнять долгие операции (например, обработку логов) без риска, что другой процесс удалит рабочий файл. Пространство на диске будет освобождено отложенно. В Windows поведение иное: попытка удалить открытый файл обычно завершается ошибкой ERROR_SHARING_VIOLATION.