← Назад к вопросам
Что произойдет если процесс А производит чтение из файла, а процесс Б пытается его удалить?
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
...
Что произошло:
- Процесс Б успешно удалил файл из каталога
- Название файла больше не существует
- Данные остаются в памяти ядра (reference counting)
- Физическое удаление только когда закроется дескриптор
Проверка на 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
Сравнение платформ
| Операция | Linux | Windows |
|---|---|---|
| Удаление открытого файла | Успешно | Ошибка |
| Доступ к данным после удаления | Да (через дескриптор) | Невозможно |
| Переименование открытого файла | Успешно | Ошибка |
Механизм Linux: Reference Counting
В Linux каждый файл имеет счётчик открытых дескрипторов:
- Открытие файла → counter++
- Удаление файла → удаляется из inode таблицы, но данные сохраняются
- Закрытие файла → counter--, если counter = 0 → физическое удаление
Восстановление данных
На Linux удалённые данные можно восстановить, пока процесс читает:
lsof | grep deleted # Найти удалённые файлы
cp /proc/PID/fd/FD ./restored_file # Восстановить
Best Practices
// RAII — гарантированное закрытие
{
ifstream file("myfile.txt");
// ... чтение ...
} // Автоматическое закрытие в деструкторе