LINUX.ORG.RU

Проверка, открыт ли файл другим приложением

 , ,


0

0

Доброго времени суток, уважаемые ЛОРовцы. Имеется файл, к которому попеременно должны иметь доступ две или более программы на C++. Для работы с файлами используются:

ifstream file1("...");
ofstream file2("...");
Каким образом можно проверить, открыт ли файл кем-то еще?

Заранее благодарен.

Если сам не научишь приложения как-то сообщать о факте открытия, то в общем виде никаким.

mashina ★★★★★ ()

Для синхронизации доступа к одному файлу из нескольких процессов можно использовать advisory locks - через flock() или fcntl().

yoghurt ★★★★★ ()

Каким образом можно проверить, открыт ли файл кем-то еще?

никаким. Разве что парсить /proc/*/fd/* (но нужны права рута)

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

Разве что парсить /proc/*/fd/* (но нужны права рута)

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

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

Для синхронизации доступа к одному файлу из нескольких процессов можно использовать advisory locks - через flock() или fcntl().

тоже не самая лучшая идея. Лучше организовать так, что-бы такой проблемы не возникало. И её обычно и не возникает, если пишет одна программа (или много программ, но append only, и flush'ат, ну как логи).

Если это не подходит, то ИМХО лучше смотреть в сторону СУБД.

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

PS:

много программ, но append only, и flush'ат

забыл сказать, что писать надо немного, по ≤512 байт, ЕМНИП.

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

Если это не подходит, то ИМХО лучше смотреть в сторону СУБД.

Ох лол..

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

что лолкаешь? Откуда я(ты) знаю, что за задача у ТСа? Может у него Over9000 транзакций в секунду? Предлагаешь flock'ать их?

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

ткуда я(ты) знаю, что за задача у ТСа? Может у него Over9000 транзакций в секунду?

Если сначала прочитать что у ТС написано и потом отвечать, то можно уж понять, что у него не может быть адского кол-ва «транзакций» и flock() существенно хуже не сделает. Его основная проблема это ~stream, к которым навряд ли получится привязать эти flock()'и без упарывания.

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

Может у него Over9000 транзакций в секунду?

Думаю, что если ТСу приходилось бы решать подобные задачи, он бы не задавал такие вопросы :)

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

stream, к которым навряд ли получится привязать эти flock()'и без упарывания.

ну он может написать велосипед на read(2)/write(2), начитавшись ваших советов. Не?

Не лучше-ли сразу организовать межпрограммное взаимодействие по-человечески, чем городить огород из былинных костылей+iostream?

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

Может у него Over9000 транзакций в секунду?

Думаю, что если ТСу приходилось бы решать подобные задачи, он бы не задавал такие вопросы :)

не так давно здесь человек уже получал Over9000 транзакций каким-то хэлловорлдом на 100 строк с flock'ами. Точнее НЕ получал, и у ЛОР спрашивал совета.

emulek ()

ЕМНИП в ядре онтопика запись строки атомарна. Строй своё приложение с учётом этого и всё будет ОК.

К тому же еть вопрос: ты собираешься читать или писать? В первом случае проблем нет. Фал можно открывать для чтения сколько угодно.

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

ЕМНИП в ядре онтопика запись строки атомарна

ядро тут ни в каком месте не работает со строками.

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

Over9000 транзакций в секунду

Не-не-не, не так много!
Просто, есть идея запилить один велосипед. Есть приложение, которое рисует в /dev/fb0 то, что передает ему куча других приложений. Т.е. запускается это самое приложение и следит за файлом, в который прилетают команды. Прилетела команда - «нарисуй то, что находится в таком-то файле с такими-то координатами». Приложение читает команду и выполняет её.
Так вот, дело в том, что все, кроме предотвращения одновременного обращения на чтение одного приложения и на запись другого, реализовано.
Была идея использовать именованный канал, но чего-то не заладилось. Второй вариант - использовать еще один файл (например, «io») для мониторинга чтения/записи (есть файл - идет процесс, нет файла - нет процесса), но мне он кажется немного костыльным.

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

Была идея использовать именованный канал, но чего-то не заладилось.

Лучше разобраться с тем, что не получилось, и использовать это.

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

Прилетела команда - «нарисуй то, что находится в таком-то файле с такими-то координатами». Приложение читает команду и выполняет её.

Через файл это точно делать не нужно. Это хорошо ляжет на пайп, до 4096b можно передать атомарно, для команд должно хватить. Есть ещё другие альтернативы, например, unix сокеты.

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

ядро тут ни в каком месте не работает со строками.

Вот и экперд. man write. Как по твоему работает запись в файл?

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

ЕМНИП в ядре онтопика запись строки атомарна.

не. Если строка >512 байт, то не факт. IRL >65536 как минимум.

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

Вот и экперд. man write. Как по твоему работает запись в файл?

Запись в файл работает блоками фиксированной длины на всех уровняхс стека. /Ваш кэп.

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

Так вот, дело в том, что все, кроме предотвращения одновременного обращения на чтение одного приложения и на запись другого, реализовано.

я не понял, как ты реализовал запись? Если через iostream, то это наверное не запись, а append, да? И в чём проблема тогда?

AFAIK проблема с append возникает тогда, и только тогда, когда ты пишешь по 100500 байт. Тогда записи перепутываются, т.е. смешиваются друг с другом.

Проблемы с чтением нет в онтопике во всяком случае. Ну с ext3/ext4 у меня никогда не было.

О какой «проблеме» ты спрашиваешь?

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

Через файл это точно делать не нужно. Это хорошо ляжет на пайп

/0

пайп тоже файл. Какая вообще разница-то? Ясное дело, что тут нужен пайп, а не регулярный файл, т.к. регулярный файл придётся чистить.

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

ядро тут ни в каком месте не работает со строками.

Вот и экперд. man write. Как по твоему работает запись в файл?

запись в файл работает по количеству байт.

Читать до полного просветления man 2 write

ssize_t write(int fd, const void *buf, size_t count);

DESCRIPTION write() writes up to count bytes from the buffer pointed buf to the file referred to by the file descriptor fd.

The number of bytes written may be less than count if, for example, there is insufficient space on the underlying physical medium, or the RLIMIT_FSIZE resource limit is encountered (see setrlimit(2)), or the call was interrupted by a signal handler after having written less than count bytes. (See also pipe(7).)

For a seekable file (i.e., one to which lseek(2) may be applied, for example, a regular file) writing takes place at the current file offset, and the file offset is incremented by the num- ber of bytes actually written. If the file was open(2)ed with O_APPEND, the file offset is first set to the end of the file before writing. The adjustment of the file offset and the write operation are performed as an atomic step.

POSIX requires that a read(2) which can be proved to occur after a write() has returned returns the new data. Note that not all file systems are POSIX conforming.

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

пайп тоже файл. Какая вообще разница-то?

Тебе мог бы мопочь man 7 pipe, но, видимо, не в этой жизни.

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

пайп тоже файл. Какая вообще разница-то?

Тебе мог бы мопочь man 7 pipe, но, видимо, не в этой жизни.

т.е. пайп ≠ файл, да?

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

т.е. пайп ≠ файл, да?

да. И сокет это тоже не файл, и таймер из timerfd_create() тоже не файл.

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

Ну хорошо. На уровне ядра всё - пайпы. А читает ядро построчно. Какая разница-то?

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

Ну хорошо. На уровне ядра всё - пайпы. А читает ядро построчно. Какая разница-то?

с тобой тоже ясно.

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

Ядро построчно? :) А если в файле нет строк, т.е. одна большая длинная, длиной в 4 Гб?

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

запускается это самое приложение и следит за файлом, в который прилетают команды. Прилетела команда - «нарисуй то, что находится в таком-то файле с такими-то координатами». Приложение читает команду и выполняет её.

ПЦ! Вот скажи мне - какого лешего ты решил использовать файлы? Только потому, что они вообще для этого не подходят? Почему на ЛОР ты запостил вопрос «как удалить гланды через жопу» вместо «как лучше удалять гланды и вообще нужно ли»?

По теме: сокеты.

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

Тебя, дорогой, тебя. Файл - набор байт. Какие нахрен строки? Еще «абзацами», или «законченными литературными произведениями» напиши.

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

Ты за приложение не расписывайся. Оно и так знает, как ему читать. Признаю - дал маху. Ядро ничего не читает. Только выполняет. Со всеми бывает.

ziemin ★★ ()

как насчет lock файла?

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

Илли более простой вариант - fuser. Но с точки зрения производительности это плохо. IMHO происходит сканированеи списка открытых файлов всех процесов.

vromanov ★★ ()

Можно файл расположить в /dev/shm и использовать всякие мутексы итд внутри файла

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