Я пишу C код, который берет свои задачи из файла (на linux). В этот файл параллельно записывается несколько процессов (с использованием echo "COMMAND" >> "file_queue_input"
). До сих пор эта логика c использовалась:
rename (file_queue_input, file_queue_process);
queue_file = fopen (file_queue_process,"r");
while (!feof (queue_file))
{
<process file line by line>
} // end of while reading queue file
fclose (queue_file);
remove (file_queue_process);
Идея заключалась в том, что при перемещении файла под другим именем новые дескрипторы будут открываться относительно исходного имени и все команды будут прочитаны. Но реальность показывает, что некоторые команды теряются в пути.
Мое предположение: дескриптор записи открывается перед операцией перемещения, остается открытым для нового имени, но еще не записал свои данные, файл читается без данных а затем дескриптор записи записывает данные, но поскольку чтение l oop уже завершено, читать данные некому, и файл удаляется. Как это предотвратить?
Как правильно читать файл очереди, в который также часто пишут? Я совершенно уверен, что я не первый человек, заинтересованный в этом, но не могу найти правильный вопрос для Google, чтобы найти что-то полезное.
Как и просили в комментариях, здесь добавлен минимальный пример (обратите внимание, что у меня есть все проверки, ведение журнала и т. д. c ... но хотелось бы, чтобы код был как можно короче, чтобы все, что не было абсолютно необходимым, было удалено): https://drive.google.com/open?id=1U9vh7DEUPopuyTJ5j4J8T8FqVj812AzV
Это содержит 2 файла: Queue_read_test.c
(файл, который я пишу, и который контролирует, как это сделать), bash_load_generator.sh
, который представляет собой файл, имитирующий записи, где я абсолютно не контролирую.
Сначала мы проверяем числа и запускаем генератор, когда генератор заканчивается sh, мы запускаем программу чтения очереди:
ice@center:/usr/src/Demo$ ./bash_load_generator.sh
All commands started waiting for finish
DONE
ice@center:/usr/src/Demo$ ./Queue_read_test # Stop with CTRL+C
^CFinished with 10000 queue items read: ice@center:/usr/src/Demo$
Затем мы запускаем первую программу чтения очереди, а затем мы запускаем генератор на 2-м экране, после того, как все закончено и файл очереди исчезает, мы останавливаемся читатель очереди (это сценарий из реальной жизни):
ice@center:/usr/src/Demo$ ./Queue_read_test # Run in screen 1
ice@center:/usr/src/Demo$ ./bash_load_generator.sh # Run in screen 2
All commands started waiting for finish
DONE
ice@center:/usr/src/Demo$ ls -ltra /tmp/ | grep queue # Check all was processed (no file should be found) in screen 2
ice@center:/usr/src/Demo$
ice@center:/usr/src/Demo$ # return to screen 1 and CTRL+C
^CFinished with 9905 queue items read: ice@center:/usr/src/Demo$
И мы видим, что 95 команд потеряно. Это для иллюстрации описанной проблемы, мой вопрос теперь, возможно, благодаря вашим комментариям более точным: Что я могу сделать как автор средства чтения очереди, чтобы предотвратить потерю команд? (без возможности изменять средства записи очереди) Могу ли я проверить, есть ли дескрипторы открытых файлов (не думаю, что я не root).