LINUX.ORG.RU

[С++][потоки] Создать новый файл без race condition

 ,


0

1

Как при помощи потоков в C++ создать новый файл без race condition? Фактически нужно чтобы в результате вызывалось open(O_EXCL).

Если сначала проверять что файла нет, а потом открывать, то образуется окно для race condition.

Это даже фортран умеет:

OPEN(..., STATUS='NEW', ...)

PS. Я негодую! Нет подсветки синтаксиса для фортрана!


А как можно вообще создать новый файл при помощи потоков, пусть и с race condition?
Я вот знаю, файлы можно создавать при помощи вызовов системного api, или при помощи других программ, которые вызывают оное.

Но при помощи потоков?

Love5an
()

А нафига вообще проверять, есть ли он? Делаешь open и проверяешь то, что он тебе вернул; если -1, то не судьба. И никаких гонок.

hdfan2
()
Ответ на: комментарий от Love5an

> Но при помощи потоков?

Видимо, имелось в виду iostream.

const86 ★★★★★
()
Ответ на: комментарий от hdfan2

> А нафига вообще проверять, есть ли он?

Как раз для разруливания гонок. Может быть нужно, чтобы с файлом работал только тот, кто его создал.

Можно поколупать fstream: нельзя ли его инициализировать открытым дескриптором. Прямого пути нет, а окольный может быть.

const86 ★★★★★
()

Предлагаю такой варинт: сначала делешь open(O_EXCL). Если open прошел успешно, создаешь fstream для файла с таким же именем, а потом закрываешь дескриптор open-а. От части гонок это избавит (если файл не удаляют и не перемещают). Ну и для красоты можно всю эту низкоуровневую возню в helper-функцию open_exclusive.

Manhunt ★★★★★
()
Ответ на: комментарий от const86

> > А нафига вообще проверять, есть ли он?
> Как раз для разруливания гонок.

как раз для разруливания гонок проверка наличия файла нафиг не нужна, т.к. она как раз и создаёт эту гонку, а вот open(…, O_CREAT | O_EXCL …) + проверка возвращаемого значения и errno её и разруливает. но какой аналог этому на плюсовых потоках — хз.

arsi ★★★★★
()
Ответ на: комментарий от arsi

> fstream имеет аналог fdopen()

Если и имеет, то не в рамках стандарта..

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

но так уж повелось, что «говорим позикс, подразумеваем си; говорим си, подразумеваем позикс» ;) а плюсы, имхо, больше таки под оффтопиком распространены…

может, в с++0х введут. в с1х ввели же… (я о O_CREAT|O_EXCL).

arsi ★★★★★
()
Ответ на: комментарий от arsi

> может, в с++0х введут

Думаю, нет. Эти флаги рассматривали при формировании предыдущего стандарта C++, и решили не включать из-за слишком сильной привязки к операционной/файловой системе.

Manhunt ★★★★★
()
Ответ на: комментарий от arsi

> как раз для разруливания гонок проверка наличия файла нафиг не нужна, т.к. она как раз и создаёт эту гонку, а вот open(…, O_CREAT | O_EXCL …) + проверка возвращаемого значения и errno её и разруливает. но какой аналог этому на плюсовых потоках — хз.
Блин, точно. Про потоки-то я и не заметил :-( Т.е., как я понял, ТСу нужно открыть поток ТОЛЬКО в том случае, если он не существует, иначе облом? Видимо, никак.

hdfan2
()
Ответ на: комментарий от hdfan2

А, нет, оказывается, МОЖНО!

#include <ostream>
#include <ext/stdio_filebuf.h>

int main()
{
    int fd=open(…, O_CREAT | O_EXCL …);
    // Тут проверить fd
    __gnu_cxx::stdio_filebuf<char> fb(fd, std::ios::ate);
    std::ostream os(&fb);
    // Enjoy!
    return 0;
}
hdfan2
()
Ответ на: комментарий от arsi

> как раз для разруливания гонок проверка наличия файла нафиг не нужна, т.к. она как раз и создаёт эту гонку, а вот open(…, O_CREAT | O_EXCL …) + проверка возвращаемого значения и errno её и разруливает

Мы говорим об одном и том же. И ТС хочет именно этого.

но какой аналог этому на плюсовых потоках — хз.

Пришли к тому, с чего начали :)

Как вариант. Делаем open. Если удачно, то, создаём fstream. И после этого закрываем дескриптор, который вернулся из open. Гонки нет, если unlink/rename делают только те, кто играет по нашим правилам. Иначе fstream может создаться не для того файла, который прошёл проверку open.

const86 ★★★★★
()
Ответ на: комментарий от const86

Не заметил, Manhunt выше предложил как раз такой же алгоритм.

const86 ★★★★★
()

> Как при помощи потоков в C++ создать новый файл без race condition?

Mutex создавай, и хватай его потоком. Как схватишь — создавай файл (или ещё что угодно).

one_more_hokum ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.