Архитектура операционной системы UNIX



              

Поводы для конкуренции - часть 2


Такой проверки, однако, не всегда достаточно, поскольку можно предположить, что какой-нибудь другой процесс создаст в любом месте файловой системы новый каталог и получит тот индекс, который ранее использовался для "c". Процесс A будет заблуждаться, думая, что он обратился к нужному индексу (). Как бы то ни было, система сохраняет свою целостность; самое худшее, что может произойти, это обращение не к тому файлу - с возможным нарушением защиты - но соперничества такого рода на практике довольно редки.


Рисунок 5.32. Соперничество процессов за индекс при выполнении функции unlink

#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>

main(argc,argv) int argc; char *argv[]; { int fd; char buf[1024]; struct stat statbuf;

if (argc != 2) /* нужен параметр */ exit(); fd = open(argv[1],O_RDONLY); if (fd == -1) /* open завершилась неудачно */ exit(); if (unlink(argv[1]) == -1) /* удалить связь с только что открытым файлом */ exit(); if (stat(argv[1],&statbuf) == -1) /* узнать состоя- ние файла по имени */ printf("stat %s завершилась неудачно\n",argv[1]); /* как и следовало бы */ else printf("stat %s завершилась успешно!\n",argv[1]); if (fstat(fd,&statbuf) == -1) /* узнать состояние файла по идентификатору */ printf("fstat %s сработала неудачно!\n",argv[1]); else printf("fstat %s завершилась успешно\n",argv[1]); /* как и следовало бы */ while (read(fd,buf,sizeof(buf)) > 0) /* чтение откры- того файла с удаленной связью */ printf("%1024s",buf); /* вывод на печать поля размером 1 Кбайт */ }

Рисунок 5.33. Удаление связи с открытым файлом

Процесс может удалить связь файла в то время, как другому процессу нужно, чтобы файл оставался открытым. (Даже процесс, удаляющий связь, может быть процессом, выполнившим это открытие). Поскольку ядро снимает с индекса блокировку по окончании выполнения функции open, функция unlink завершится успешно. Ядро будет выполнять алгоритм unlink точно так же, как если бы файл не был открыт, и удалит из каталога запись о файле. Теперь по имени удаленной связи к файлу не сможет обратиться никакой другой процесс. Однако, так как системная функция open увеличила значение счетчика ссылок в индексе, ядро не очищает содержимое файла при выполнении алгоритма iput перед завершением функции unlink. Поэтому процесс, открывший файл, может производить над файлом все обычные действия по его дескриптору, включая чтение из файла и запись в файл. Но когда процесс закрывает файл, значение счетчика ссылок в алгоритме iput становится равным 0, и ядро очищает содержимое файла. Короче говоря, процесс, открывший файл, продолжает работу так, как если бы функция unlink не выполнялась, а unlink, в свою очередь, работает так, как если бы файл не был открыт. Другие системные функции также могут продолжать выполняться в процессе, открывшем файл.




Содержание  Назад  Вперед