В момента се боря с това как да реша подобен проблем, което ме доведе до вашия въпрос. Както виждам, същността е следната:
int fd = open(path, O_CREAT|O_RDWR|O_EXCL, mode);
if (fd == -1)
{
/* File already exists. */
the_file_already_exists(fd);
}
else
{
/* I just now created the file. Now I'll lock it. */
/* But first I'll deliberately create a race condition!! */
deliberately_fork_another_process_that_handles_file(path);
int code = flock(fd,LOCK_EX);
if (code < 0)
{
perror("flock");
exit(1);
}
/* I now have the exclusive lock. I can write to the file at will --
or CAN I?? See below. */
write_to_the_file_at_will(fd);
}
Очевидно в реалния живот никога не бих създал това състезателно състояние, но неговият еквивалент със сигурност може да се случи случайно в реална система. Този друг процес може например да отвори файла за четене, да получи споделена ключалка за него и да прочете файла. Ще види празен файл. Това може да означава, че е в ход операция за запис, но може да означава, че файлът е просто празен и това е правилният и окончателен отговор.
Ако празните файлове не са разрешени, четецът може просто да се държи точно както би се държал, ако файлът липсваше. В крайна сметка, ако четецът беше стартирал милисекунда по-рано, така или иначе нямаше да успее да отвори файла. В този случай читателят трябва да провери дали файлът е празен, след като го отвори.
Ако празните файлове СА позволени, значи сте в малко затруднение и аз нямам готов отговор за това.
Проблемът, който имам, е, че когато файлът е създаден за първи път, искам да запиша някаква стойност по подразбиране в него, защото искам да „автоматично инициализирам“ нова система, без да се налага да създавам предварително всеки възможен файл, който може да се нуждае. Този друг процес, който обработва файла, може самият вече да го е инициализирал! Доколкото знам, три други процеса може също да са стартирали междувременно и да са променили стойността. В такъв случай със сигурност не искам да "пиша във файла по желание" след получаване на изключителното заключване, защото ще изтрия всички тези промени.
Предполагам, че отговорът е за моя код по-горе, за да се увери, че файлът е празен, преди да пише в него. Ако НЕ е празен, тогава кодът трябва да се държи точно така, сякаш файлът вече съществува: т.е. трябва да извика:
the_file_already_exists(fd);
Може би най-важното в цялата тази дискусия е, че всеки процес, който обработва файла по някакъв начин, трябва да провери дали е празен и да се държи по съответния начин. Отново обаче, ако празните файлове СА разрешени, тогава все още не мога да се сетя за никакво гарантирано решение. Нищо от това не би било необходимо, ако имаше някакъв начин да се създаде файлът и да се заключи като единична атомна последователност, но не мисля, че има начин да се направи това.
person
Patrick Chkoreff
schedule
21.06.2018