Чи можна запускати програми частіше, ніж кожні 10 секунд?


8

У мене є такі послуги, як ця, яку я б хотів запустити майже одразу після зміни файлів.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN
http://www.apple.com/DTDs/PropertyList-1.0.dtd>
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>test</string>
    <key>ProgramArguments</key>
    <array>     
        <string>say</string>
        <string>a</string>
    </array>
    <key>WatchPaths</key>
    <array>
        <string>/Users/username/Desktop/</string>
    </array>
</dict>
</plist>

Навіть якщо для ThrottleInterval було встановлено значення 1 або 0, вони працюють лише максимум кожні 10 секунд.

9/9/12 4:57:05.457 PM com.apple.launchd.peruser.501[138]: (test) Throttling respawn: Will start in 7 seconds
9/9/12 4:57:09.541 PM com.apple.launchd.peruser.501[138]: (test) Throttling respawn: Will start in 3 seconds

man launchd.plist говорить лише про те, що програми за замовчуванням не працюють більше кожні 10 секунд, але не зазначає, що ThrottleInterval не можна було встановити нижче цього.

ThrottleInterval <integer>
This key lets one override the default throttling policy imposed on jobs by launchd.
The value is in seconds, and by default, jobs will not be spawned more than once
every 10 seconds.  The principle behind this is that jobs should linger around just
in case they are needed again in the near future. This not only reduces the latency
of responses, but it encourages developers to amortize the cost of program invoca-
tion.

Ви можете тримати програму чи сценарій протягом 10 секунд і слідкувати за змінами щосекунди:

#!/bin/bash

start=$(date +%s)
prev=

until (( $(date +%s) >= $start + 10 )); do
    new=$(stat -f %m ~/Desktop/)
    [[ $prev != $new ]] && say a
    prev=$new
    sleep 1
done

Або те саме в Ruby:

#!/usr/bin/env ruby

start = Time.now
prev = nil

until Time.now >= start + 10
  current = File.mtime("#{ENV['HOME']}/Desktop/")
  `say a` if current != prev
  prev = current
  sleep 1
end

Але чи є якийсь спосіб обійти або зменшити часовий ліміт? Це також стосується дій папок.

Відповіді:


9

Немає можливості обійти або зменшити часовий ліміт.

У документації Apple щодо створення запущених робочих місць зазначено наступне:

Важливо Якщо ваш демон демонструється занадто швидко після запуску, запуск може подумати, що він вийшов з ладу. Демони, які продовжують цю поведінку, можуть бути призупинені та не запущені знову, коли надійдуть майбутні запити. Щоб уникнути такої поведінки, не вимикайте принаймні 10 секунд після запуску.

Вашій програмі чи сценарію потрібно тривати принаймні 10 секунд. Подумайте про те, щоб здійснити цикл, щоб перевірити дати зміни файлів за останні десять секунд, спати протягом десяти секунд та повторити.

Крім того, ви можете переглядати конкретні файли, використовуючи API kqueue або FSEvents. Це питання StackOverflow може бути корисним, на рівні файлів повідомлень про зміни в файлову систему Mac OS X .


2

Ви можете тримати свій сценарій у циклі, перевіряючи модифіковані файли, а не виходити з нього, коли це буде зроблено. Після сну кілька секунд після перевірки змінених файлів. Якщо він знайде модифіковані файли, продовжте сценарій. Якщо ні, то спати знову.

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


Схоже, що запускається інший екземпляр, якщо попередній все ще працює.
Лрі

startd не запустить кілька примірників одного і того ж квитка на роботу.
Грем Мілн

1

Якщо вам потрібно запускати сценарій частіше, ніж кожні 10 секунд, це може бути дорого з точки зору "розгортання" (читайте: виділення пам'яті, запуск нових процесів тощо).

Тому в цьому випадку найкраще написати власний " демон " (програма, що працює у фоновому режимі)

Я рекомендую вам використовувати "більш здатну" мову як BASH (моя улюблена - "perl", але рубін також добре), тому що хороший демон справляється з таймаутами, тривожними сигналами тощо. (Звичайно, демон може також запускати ваші баш сценарії - якщо потрібно). Основи:

  • скрипт, що працює нескінченно і чекає якоїсь події. Подія може бути деяким мережевим входом, простим таймером або будь-яким подібним. Коли подія прибуде (наприклад, стан очікування закінчилося), сценарій виконає все, що вам потрібно, і цикл повториться.

У світі Perl вже є модулі, які налаштовують ваш сценарій як "демон", наприклад Proc :: Daemon . Я не маю досвіду з рубіном, але ця стаття може вам допомогти.

Ви можете запустити демон-процес через Launchd при запуску системи або через додаток автоматизатора при вході в систему або з терміналу вручну.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.