Launchd programları 10 saniyeden daha sık çalıştırabilir mi?


8

Dosyalar değiştirildikten hemen sonra çalıştırmak istediğim gibi bazı hizmetlerim var.

<?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 veya 0 olarak ayarlanmış olsa bile, bunlar en fazla 10 saniyede bir çalıştırılır.

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 yalnızca programların varsayılan olarak her 10 saniyede bir çalışmadığını, ancak ThrottleInterval'ın bunun altında ayarlanamayacağını söylemez.

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.

Programı veya komut dosyasını 10 saniye boyunca çalıştırabilir ve her saniye değişiklikleri izleyebilirsiniz:

#!/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

Ya da aynı şey Ruby'de:

#!/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

Ancak zaman sınırını atlamanın veya azaltmanın bir yolu var mı? Klasör eylemleri için de geçerlidir.

Yanıtlar:


9

Zaman sınırını atlamanın veya azaltmanın bir yolu yoktur.

Apple'ın Launchd Jobs Oluşturma ile ilgili belgeleri aşağıdakileri belirtir:

Önemli Programınız başlatıldıktan sonra çok hızlı bir şekilde kapanırsa, launchd çöktüğünü düşünebilir. Bu davranışı sürdüren arka plan askıya alınabilir ve gelecekteki istekler geldiğinde yeniden başlatılamaz. Bu davranışı önlemek için, başlattıktan sonra en az 10 saniye kapatmayın.

Programınızın veya komut dosyanızın en az 10 saniye boyunca çalışmaya devam etmesi gerekir. Son on saniyedeki dosya değiştirme tarihlerini kontrol etmek, on saniye uyumak ve tekrarlamak için bir döngü uygulamayı düşünün.

Alternatif olarak, kqueue veya FSEvents API'larını kullanarak belirli dosyaları izleyebilirsiniz . Bu StackOverflow sorusu, Mac OS X'te Dosya düzeyinde dosya sistemi değişikliği bildirimi yardımcı olabilir .


2

Komut dosyanızı, tamamlandığında çıkmak yerine değiştirilen dosyaları kontrol eden bir döngüde çalıştırabilirsiniz. Değiştirilen dosyaları kontrol ettikten sonra birkaç saniye uyutun. Değiştirilmiş dosyalar bulursa, komut dosyasına devam edin. Değilse, tekrar uyu.

Daha sonra, önceki çalıştırmanın ölmesi durumunda, komut dosyanızı x dakikada bir başlatmasını isteyin. Başka bir örneğin zaten çalışıp çalışmadığını kontrol etmek için komut dosyanızın başlangıcını kodlayın ve varsa çıkın.


bir önceki örnek hala çalışıyorsa, launchd başka bir örneği başlatmış gibi görünmüyor.
Lri

launchd aynı iş biletinin birden fazla örneğini başlatmaz.
Graham Miln

1

Bir komut dosyasını her 10 saniyeden daha sık başlatmanız gerekiyorsa, "çatallama" (pahalı: bellek ayırma, yeni işlemler başlatma vb.) Açısından pahalı olabilir.

Bu nedenle, bu durumda kendi " daemon " (program, arka planda çalışan) yazmak için en iyisidir

BASH olarak "daha yetenekli" bir dil kullanmanızı tavsiye ederim (en sevdiğim "perl", ama yakut da iyi) çünkü iyi bir arka plan programı zaman aşımlarını, alarmları ve benzerlerini işliyor - saf bash'da çok zor olan şeyler. (Elbette, daemon bash betiklerinizi de çalıştırabilir - gerekirse). Temel bilgiler:

  • sonsuz çalışan ve bazı olay için bekleyen komut dosyası. Olay bir ağ girişi veya basit bir zamanlayıcı veya benzeri bir şey olabilir. Olay geldiğinde (örn. Bekleme durumu sona erdiğinde) komut dosyası istediğinizi yapar ve döngü tekrar eder.

Perl dünyasında, betiğinizi "daemon" işlemi olarak ayarlayan modüller zaten var, örneğin Proc :: Daemon . Ruby ile deneyimli değilim, ama bu makale size yardımcı olabilir.

Arka plan sürecinizi sistem başlangıcında Launchd aracılığıyla veya oturum açarken automator uygulamasından veya Terminal'den manuel olarak başlatabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.