← Назад к вопросам

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

2.0 Middle🔥 191 комментариев
#Linux и операционные системы#Многопоточность и синхронизация

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что произойдёт при удалении файла, который читается?

Краткий ответ

Linux/Unix — файл удаляется из каталога, но данные остаются в памяти, пока открыт дескриптор Windows — удаление заблокируется (ERROR_SHARING_VIOLATION)

Детально: Linux/Unix

В Unix файловой системе удаление по имени отделено от удаления данных. Файл удаляется из каталога, но содержимое сохраняется, пока есть открытые дескрипторы.

// Процесс А — чтение
#include <iostream>
#include <fstream>
#include <unistd.h>

using namespace std;

int main() {
    ifstream file("myfile.txt");
    
    cout << "Процесс А: Файл открыт\\n";
    
    for (int i = 0; i < 10; ++i) {
        string line;
        getline(file, line);
        cout << "Прочитал: " << line << "\\n";
        sleep(1);
    }
    
    return 0;
}
// Процесс Б — удаление
#include <iostream>
#include <unistd.h>

using namespace std;

int main() {
    sleep(2);
    
    cout << "Процесс Б: Удаляю файл\\n";
    
    int result = unlink("myfile.txt");
    
    if (result == 0) {
        cout << "Процесс Б: Файл удалён из каталога\\n";
    } else {
        perror("Ошибка");
    }
    
    return 0;
}

Результат на Linux

Процесс А: Файл открыт
Прочитал: строка 1
Прочитал: строка 2
Процесс Б: Удаляю файл
Процесс Б: Файл удалён из каталога
Прочитал: строка 3
Прочитал: строка 4
...

Что произошло:

  1. Процесс Б успешно удалил файл из каталога
  2. Название файла больше не существует
  3. Данные остаются в памяти ядра (reference counting)
  4. Физическое удаление только когда закроется дескриптор

Проверка на Linux

# Запустить чтение в фоне
./process_a &
PID=$!

# Удалить файл
rm myfile.txt

# Восстановить через /proc
cp /proc/$PID/fd/3 ./recovered_file.txt

# Файл всё ещё доступен!
cat ./recovered_file.txt

Windows — совсем другое

Windows блокирует удаление:

#include <Windows.h>
#include <iostream>

using namespace std;

int main() {
    HANDLE hFile = CreateFileA("myfile.txt", GENERIC_READ, 
                               0, NULL, OPEN_EXISTING, 0, NULL);
    
    if (hFile != INVALID_HANDLE_VALUE) {
        cout << "Файл открыт\\n";
        
        if (DeleteFileA("myfile.txt")) {
            cout << "Удаление успешно\\n";
        } else {
            cout << "ОШИБКА: ERROR_SHARING_VIOLATION\\n";
        }
        
        CloseHandle(hFile);
    }
    
    return 0;
}

Результат:

Файл открыт
ОШИБКА: ERROR_SHARING_VIOLATION

Сравнение платформ

ОперацияLinuxWindows
Удаление открытого файлаУспешноОшибка
Доступ к данным после удаленияДа (через дескриптор)Невозможно
Переименование открытого файлаУспешноОшибка

Механизм Linux: Reference Counting

В Linux каждый файл имеет счётчик открытых дескрипторов:

  1. Открытие файла → counter++
  2. Удаление файла → удаляется из inode таблицы, но данные сохраняются
  3. Закрытие файла → counter--, если counter = 0 → физическое удаление

Восстановление данных

На Linux удалённые данные можно восстановить, пока процесс читает:

lsof | grep deleted  # Найти удалённые файлы
cp /proc/PID/fd/FD ./restored_file  # Восстановить

Best Practices

// RAII — гарантированное закрытие
{
    ifstream file("myfile.txt");
    // ... чтение ...
}  // Автоматическое закрытие в деструкторе
Что произойдет если процесс А производит чтение из файла, а процесс Б пытается его удалить? | PrepBro