2015-08-18 5 views
3

У меня странная проблема с моей работой crontab. Моя работа crontab делает следующее:Is bash> перенаправление атома?

program > file 

Иногда, однако, файл заполняется случайными данными, которые я не могу объяснить.

Интересно, может ли быть предыдущая работа crontab, которая занимает больше времени, и она каким-то образом смешивает свои результаты с file с текущей работой crontab?

Общая информация Мой вопрос: есть > Эксплуатация атома? Значение, если две программы делают > file, то последний, который будет завершен, будет иметь свои данные в file?

+0

Если вы хотите просто избежать одновременного запуска двух экземпляров вашей программы, вы можете использовать 'GNU Parallel', но вызывать его как' sem -id mySemaphore program' для создания семафора типа mutex. –

+0

@MarkSetchell Вы имеете в виду, что я должен просто запустить свою работу cron параллельно? – bodacydo

+0

http://www.gnu.org/software/parallel/man.html#EXAMPLE:-Working-as-mutex-and-counting-semaphore –

ответ

3

Нет, это не атомный. Даже не немного атомный.

Перенаправление делает две вещи:

  1. Это открывает файл по имени, создавая его, если это необходимо.

  2. Он усекает файл.

После этого, утилита запускается с его stdin присвоенного открытого файла.

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

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

+0

Спасибо за ответ. Итак, что произойдет в конце, если два процесса будут записывать в один и тот же файл одновременно, перезаписывая друг друга? Смогу ли я получить данные о мусоре, которые я описал? Или он будет содержать вывод последнего процесса, который заканчивает запись в процесс? – bodacydo

+2

@bodacydo: Как правило, вы получите мусор.Каждый процесс записывает в свою собственную позицию записи, и эти два процесса являются асинхронными относительно друг друга, поэтому вы получите несколько байтов от одного и нескольких байтов от другого. Вы можете даже получить пробелы, если вам не повезло. – rici

2

Это не атомный. Вы можете проверить это легко себе:

({ echo a ; sleep 3; echo b ; } > 1) & 
({ echo c ; sleep 1 ; echo d ; } > 1)& 

sleep 5 ; cat 1 
2

Баш > делается с open с флагами (для Баш 4.3.30, по крайней мере) O_TRUNC | O_WRONLY | O_CREAT (от линии 707 make_cmd.c)

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

Смежные вопросы