2009-11-06 15 views
33

Subprocess.call kullanarak bir python işleminden ürettiğim harici komut satırı uygulamaları tarafından çekilen zaman ve cpu miktarını sınırlamam gerekiyor çünkü temel olarak bazen oluşturulan işlem sıkışıyor ve CPU'yu% 99 oranında iğneliyor.Python: subprocess.call/subprocess.Popen için ulimit ve güzel mi?

güzel ve ulimit bunu yapmak için makul yollar gibi görünüyor, ancak alt işlemlerle nasıl etkileşime gireceğinden emin değilim. o

  • Limiti o cpu
  • % 20'sine 60 saniyeden sürdüğü takdirde sınırlayıcı kaynak uygulamak istediğiniz işlemi öldür
    • :
      • sınırlar

        şuna benzer Alt süreçleri doğuran python işlemine değil, alt işlemlere.

      Subprocess.call üreme işlemine nice ve ulimit uygulanmasının bir yolu var mı? Daha iyi python-yerli alternatifler var mı?

      Bu bir linux (ubuntu) sistemindedir.

  • +1

    Cevabım yerine en çok oylanan yanıtı kabul etmek isteyebilirsiniz. Benimkinden çok daha iyi. –

    cevap

    10

    Böyle ulimit ve nice kabuk komutlarıyla subprocesses sınırlarını ayarlayabilirsiniz:

    import subprocess 
    subprocess.Popen('ulimit -t 60; nice -n 15 cpuhog', shell=True) 
    

    işlemci zamanını 60 saniyelik bir limit ve olduğu 15. Not bir incelik ayarı ile cpuhog çalışır % 20 CPU gazı ayarlamanın kolay bir yolu yoktur. İşlem başka bir (daha az hoş) işlemin de CPU'ya ihtiyaç duymadığı sürece% 100 CPU kullanacaktır.

    +0

    Teşekkürler Ville, açıkladığınız işlemci büyük çalışıyor. Komutu, dizge yerine dizge sözdizimi ile aynı şeyi yapmak mümkün olup olmadığını biliyor musunuz? – Parand

    +0

    Anlatabildiğim kadarıyla, tüm kabuk komutunu çalışmak için böyle bir şey için tek bir dizede geçirmeniz gerekir. –

    +1

    Bu gerçekten kabul edilen yanıt olarak işaretlenmesi gereken çözüm değildir. Kullanıcı tarafından sağlanan parametrelerle kombinasyon halinde, bu bir güvenlik deliğinin açılmasıyla kolaylıkla sonuçlanabilir. –

    86

    Alt işlem için preexec_fn parametresini kullanın.Popen ve kaynak modülü. Örnek:

    parent.py:

    #!/usr/bin/env python 
    
    import os 
    import sys 
    import resource 
    import subprocess 
    
    def setlimits(): 
        # Set maximum CPU time to 1 second in child process, after fork() but before exec() 
        print "Setting resource limit in child (pid %d)" % os.getpid() 
        resource.setrlimit(resource.RLIMIT_CPU, (1, 1)) 
    
    print "CPU limit of parent (pid %d)" % os.getpid(), resource.getrlimit(resource.RLIMIT_CPU) 
    p = subprocess.Popen(["./child.py"], preexec_fn=setlimits) 
    print "CPU limit of parent (pid %d) after startup of child" % os.getpid(), resource.getrlimit(resource.RLIMIT_CPU) 
    p.wait() 
    print "CPU limit of parent (pid %d) after child finished executing" % os.getpid(), resource.getrlimit(resource.RLIMIT_CPU) 
    

    child.py:

    #!/usr/bin/env python 
    
    import os 
    import sys 
    import resource 
    
    print "CPU limit of child (pid %d)" % os.getpid(), resource.getrlimit(resource.RLIMIT_CPU) 
    

    parent.py yeni bir işlem haline bölünür. Yeni işlemde, setlimits() öğesini arayacak, ardından child.py. Bu, kaynağın çocuk işleminde sınırlandırılacağı, ancak ebeveynte sınırlı olmayacağı anlamına gelir.

    Çıktı çalışan programı:

    ./parent.py 
    CPU limit of parent (pid 17404) (-1, -1) 
    Setting resource limit in child (pid 17405) 
    CPU limit of parent (pid 17404) after startup of child (-1, -1) 
    CPU limit of child (pid 17405) (1, 1) 
    CPU limit of parent (pid 17404) after child finished executing (-1, -1) 
    

    buna genellikle çirkin parametreyi neden, özellikle de her zaman kabuk aracılığıyla alt işlemi yumurtlamaya için iyi bir fikir değil, bu durum birçok durumda ulimit kullanmaya çalışırken daha iyi bir çözümdür beladan alıntı yapmak.

    +0

    Teşekkürler Erik. Bu, dış süreçte değil, python sürecindeki sınırları belirler gibi görünüyor mu? – Parand

    +0

    Python süreci ve tüm çocukları. (Yani, olması gerektiği gibi.))) Man sayfasından: Sistem kaynaklarının mevcut süreçlere göre tüketimi ve oluşturduğu her işlem getrlimit() çağrısı ile alınabilir ve setrlimit ile ayarlanabilir.() aramak. –

    +2

    Evet, kaynak paketi python işleminin sınırını ayarlar (setrlimit aracılığıyla) - fakat benim örneğimde, alt işlemi yürütmek için exec() işlevini çağırmadan önce alt işlemlerin oluşturduğu alt işlemin sınırını ayarlar. Yani, örnekte, çağrı süreci 'sınırları sadece etkilenmez, sadece çocuğun sınırları. –

    6

    Erik benim için kolaylaştırdı ama Zengin Sivri nice bölümünü unuttum. psutil paketini güzel (pun amaçlı) buluyorum ama maalesef daha az taşınabilir.

    import os 
    import psutil 
    import resource 
    import subprocess 
    
    def preexec_fn(): 
        pid = os.getpid() 
        ps = psutil.Process(pid) 
        ps.set_nice(10) 
        resource.setrlimit(resource.RLIMIT_CPU, (1, 1)) 
    
    print "mother pid", os.getpid() 
    p = subprocess.Popen(["./cpuhog.sh"], preexec_fn=preexec_fn) 
    p.wait() 
    print "mother still alive with pid", os.getpid() 
    

    Villeshell=True hangi ben bir şekilde alerjim var derdi: Burada söz benim almaktır. Belki de burada yaşlı ve huysuzum ama bunu engellemeye çalışıyorum!

    +3

    Python’un yerleşik yapısı "güzel" olduğunda neden psutil’e ihtiyacınız var? – WGH

    +0

    Muhtemelen bir PID'yi "os.nice" ye geçiremediğinizden, fakat 'psutil' yapabileceksiniz. –

    İlgili konular