Uruchom wiele zadań CRON, gdzie jedno zadanie zajmuje dużo czasu

16

Mam następujące ogólne pytanie dotyczące zadań crona.

Załóżmy, że mam następujące elementy crontab:

* 10 * * * * someScript.sh
* 11 * * * * someScript2.sh
30 11 */2 * * someScript3.sh  <-- Takes a long time let's say 36 hours.
* 12 * * * someScript4.sh

Czy jest wystarczająco inteligentny, aby uruchomić pozostałe zadania w odpowiednim czasie? Na przykład długi skrypt nie musi się kończyć?

Co się stanie, jeśli początkowy długi skrypt nadal działa i zostanie ponownie wywołany przez crona?

Dziękuję Ci!

użytkownik1357015
źródło
Cron nie dba o to, jak długo działają zadania; uruchomi dodatkowe kopie.
Jeff Schaller
Upewnij się, że twoje pytania są poprawnie sformatowane.
Bram

Odpowiedzi:

31

Każde zadanie cron jest wykonywane niezależnie od wszelkich innych określonych przez ciebie zadań. Oznacza to, że Twój długowieczny skrypt nie utrudni wykonywania innych zadań w określonym czasie.

Jeśli którykolwiek ze skryptów nadal wykonuje się przy następnym zaplanowanym interwale cron, zostanie wykonana kolejna, równoczesna instancja skryptu.

Może to mieć nieprzewidziane konsekwencje w zależności od tego, co robi skrypt. Poleciłbym przeczytać artykuł w Wikipedii na temat blokowania plików , w szczególności sekcję dotyczącą blokowania plików . Plik blokujący jest prostym mechanizmem sygnalizującym, że zasób - w twoim przypadku someScript3.shskrypt - jest obecnie „zablokowany” (tj. W użyciu) i nie powinien być uruchamiany ponownie, dopóki plik blokujący nie zostanie usunięty.

Spójrz na odpowiedzi na następujące pytanie, aby uzyskać szczegółowe informacje o sposobach implementacji pliku blokady w skrypcie:

ciasto duszne
źródło
8

Nie jestem pewien, co masz na myśli przez odpowiedni czas. Cron rozpocznie pracę o wyznaczonej godzinie. Nie sprawdza innych zaplanowanych zadań ani innych wystąpień zadania.

Zatem wszelkie zdefiniowane ważne zadania zostaną uruchomione w zdefiniowanym czasie. Każde zadanie, które działa dłużej niż zdefiniowany interwał, zostanie uruchomione wiele razy. Obowiązkiem każdego, kto napisał to zadanie, jest uniemożliwienie jego wielokrotnego uruchomienia, jeśli jest to wymagane. Sprawdzając np. Plik blokady, plik PID lub coś takiego.

Istnieją oczywiste ograniczenia liczby procesów, które mogą być uruchomione równolegle, ale nie są one specyficzne dla cron.

Bram
źródło
6

Oprócz innych odpowiedzi, zwłaszcza linku opublikowanego przez @soulcake: Jeśli zaplanujesz długo działające polecenie ze zbyt krótkimi przerwami, cron z przyjemnością wykona drugie przed zakończeniem pierwszego (chyba że w poleceniu zaimplementowano jakiś muteks) .

To często spowalnia pierwotne polecenie jeszcze bardziej, prowadząc do uruchomienia innej instancji przed zakończeniem poprzednich, itp. Lub może być niepożądane z innych powodów.

Ogólnym sposobem zapobiegania jest warunek uruchomienia polecenia z osłoną, która zapewnia, że ​​poprzednie polecenie nie jest uruchomione. Na przykład:

10 * * * * pgrep my_slow_command >/dev/null || /usr/local/bin/my_slow_command

Upewnij się, że pgrep pasuje do nazwy polecenia, gdy jest uruchomione, np. Skrypty Pythona mają python jako nazwę pliku wykonywalnego, co prawdopodobnie nie jest wystarczająco szczegółowe i musisz dopasować również do nazwy skryptu pytona.

10 * * * * pgrep -f my_script.py || /usr/local/bin/my_script.py

(pgrep bez opcji -f pasuje jednak do nazw skryptów bash)

Jeśli z jakiegoś powodu nie możesz użyć pgrep:

10 * * * * ps ax | grep [m]y_command || /usr/local/bin/my_command

Nawiasy są używane, aby uniknąć dopasowania samej komendy grep.

Edheldil
źródło
0

Używam flock.

* * * * * exec flock --nonblock .ws_client.lock -c ws_client.py >& /tmp/ws_client.out
JohnMudd
źródło