Python kaynak duruma göre işlem yönetimi

merhabalar arkadaşlar bir biyoinformatik sürecinde kullanılmak üzere kontrol scripti yazmak istiyorum. çalıştığım datalar ortalama 8-10GB boyutlarda haliyle hayli zaman alıyor süreçlerin tamamlanıp anlamlı veriler elde etmek (duruma göre 16 komut). Yürüttüğüm komutlar ortalama olarak 1-2 saat kadar sürüyor bir komutun çıktısı diğer komutun girdisi olarak kullanılıyor. şimdiye kadar geldiğim noktada RAM CPU ve Swap kaynaklarımın ne kadar kullanıldığını % formatında ve boş-dolu alanları boyut(GB) cinsinde işlemci için ise total kullanım yüzdesi şeklinde elde edebiliyorum. bunu psutil kütüphanesini kullanarak elde ediyorum. yapmak istediğim olay şu 8 farklı datayı kaynakların durumlarını kontrol ederek 1. data işleme başladıktan sonra yeterli müsaitlik bulunuyor ise 2. datayı işleme almak tekrar kontrol ile 3-4-5-6-7-8 şeklinde devam etmek istiyorum. sürekli bu durumları kontrol eden bir scripti nasıl yazabilirim.

Merhaba.

Yeterli müsaitlik tam olarak ne oluyor?

resource modülünü kullanın diyeceğim ama niye bilmiyorum, girdiğim değerler RLIMIT_DATA için işe yaramıyor. Dosya’ya yazılacak veri miktarını kontrol etmek için RLIMIT_FSIZE kullandım çalıştı. Ama bu RLIMIT_DATA bir türlü istediğim gibi çalışmadı. Acaba RLIMIT_DATA yerine RLIMIT_STACK mi kullanmam gerekiyor diye şüphelendim ama o da istediğim gibi çalışmadı. :confused:

import resource

resource.setrlimit(resource.RLIMIT_DATA, (2 ** 3, 2 ** 3))

a = []
for i in range(10000):
    print(i)
    a.append(i)

MemoryError hatasını i = 4769 olduğunda veriyor. Niye böyle yapıyor anlayamadım.

4769
Traceback (most recent call last):
  File "/home/tanberk/Projects/Exercises/e1.py", line 12, in <module>
MemoryError

Dokümantasyonda şöyle bir ifade var:

resource. RLIMIT_DATA *

The maximum size (in bytes) of the process’s heap.

8 bayt ayarladığımı sanıyorum ama a listesine eklediğim veriler zaten 8 baytı geçmiyor mu?

Hatta a listesine i değil de bytes(i) eklemeye çalıştığımda bu sefer i=628 indeksinde başlıyor MemoryError’ı yükseltmeye. str(i) eklemeye çalışırsam da i=2623 indeksinde MemoryError yükseltiliyor.

Ekrem hocam yeterli müsaitlik durumu dediğim olay şu birinci data işleme alındı zaman bir miktar ram ve cpu kullanımını gerçekleşiyor ve 2. Datanın işleme alınmadan önce ramde ve cpuda 2. Datanın kullanacağı kadar boşluk olup olmadığını kontrol etmek istiyorum eğer var ise 2. Data da işleme alınacak yoksa 2. Data bekletilecek

hocam sanırım resource kütüpnesi ile değilde threading kütüphanesi daha efektif olabilir zaten hali hazırda anlık ram ve işlemci durumlarını kontrol ediyorum benim yapmak istediğim olay şu 1. data işleme alındıktan sonra 2. datayı işleme almak için yeterli boşluk varmı onu kontrol edip varsa sorun yok zaten komut yürücek ancak yeterli boşluk yok ise 2. datanın sırada ki komutunu askıya alması gerekiyor ve ilk uygunluk olduğu zaman tekrar 2. datayı işleme alması gerekiyor tahminimce bunu da şu şekilde başarabiliriz 1. data işlenirken arka planda sürekli işlemci ve ram kontrolü yapılacak ve uygun boşluk değeri yakalandığı zaman 2. datanın askısı iptal edilip oda işleme alınacak

CPU kullanımını sınırlandırmak gereksiz geldi bana, hatta yapacağınız işlemler uzun sürdüğü için multiprocessing önerecektim. Zaten CPU kullanımı işlemlerinizi kaç farklı çekirdekte çalıştırdığınızla ve işlemlerin arada bir durup durmaması ile alakalı, boş bir döngünün bile işlemci kullanımını çok fazla arttırdığını daha önce forumda konuşmuştuk.

RAM’ı kontrol edecek sanırım.

2. işlemi durdurduk diyelim, 2. işlemin bellekte harcadığı alan kalmaya devam edecek.

Bence böyle ilginç çözümler yerine optimizasyon yapmaya çalışın. Anladığım kadarı ile asıl sıkıntı bellek, belleğiniz kaç GB mesela? Bu 8 işlemin her biri birbirinden ayrı veriler ile mi çalışacak? Eğer öyle ise multiprocessing kullanılabilir. Bu işlemler verinin tek seferde ne kadarlık bir kısmına ihtiyaç duyuyor? Veriyi diskten yavaş yavaş okuyabiliriz, belleği rahatlatacaktır. Eğer (varsa) kullandığınız kütüphaneye bu verileri tek seferde veriyorsanız kütüphanenin iterable’lar ile çalışıp çalışmadığı kontrol edilebilir.


Her şeyden önce bu modülün Unix için olduğunu söylememiz lazım, Windows’da kullanılamaz (yok zaten).

Hem kütüphane belli bir bellek aşıldığında hata yükselmesine sebep oluyor, bu işte kullanılması zor diye düşünüyorum.

Toplamı baya bir geçiyor, her biri tek başına da geçiyor. Hem bu 8 bayt toplam heap’ı vermiyor mu?

cpu kullanımı şu şekilde sınırlandırılacak datayı işlemesi için 16 threadtan 2 tanesi 1 data seti için tahsis edilecek ve bu şekilde 8 data için tüm threadlar kullanılmış olucak burda ki esas mesela ram kullanımı sistemde 128GB ram bulunuyor ve bu da 8 adet data için yeterli bir miktar bellek (bir data ortalama 8gb kadar bellek kullanır) işlem yürütme esnasında durdurma olmayacak zaten düşündüğüm şu diyelim hali hazırda 2 data için işlem yapılıyor bu demek oluyor ki 4 tread ve 16 gb bellek tüketiliyor olası bir durumda 3. datanın başlatılması için bu bellek durumu kontrol edilip karar verilecek ve 3. data için 16 komut adım adım yürütülecek her yürütülen komuttan sonra bu bellek kullanım miktarı kontrol edilecek eğer uygun değil ise başlatılmayacak askıda beklicek benim oluşturamadığım nokta bu if else yapısı ile bellek durumunu kontrol ediyorum ancak askıya alınan bir işlemi tekrar başlatamıyorum

:slight_smile: Sizi kandırmışlar, Python’da threadlar tek çekirdek üzerinde çalışır.

bu kullanımı python ile sağlamıyorum zaten vereceğim komut başla bir programı tetikleyecek ve datayı işleyerek bir çıktı üreticek python sadece tetikleyici olarak kullanılacak

Hmm, tamam o zaman. Bunu fark etmemiştim, siz de tam vurgulamamıştınız sanırım.

Bu komutlar arasında bekleyebiliyoruz yani, değil mi?

Uygun belleğin ne olduğuna karar verelim.

Askıdaki işlemlerin nasıl bir yapıya sahip olduğunu açarsanız daha rahat çözüm üretiriz. Sanırım her işlem için bir uygulamayı subprocess ile açıyorsunuz, doğru mu?

komutlar şu şekilde oluyor bir komutun çıktısı diğer komutun girdisi şeklinde ilerliyor
uygun bellekten kastım her bir ham data işlenmesinde 16 komut içerisinde en fazla data başına 10GB bellek kullanımı söz konusu yani ramde 9GB boşluk bulunuyor ise komut askıya alınacak
tam olarak subprocess kullanmıyorum kullanacağım modul os ile terminale komut göndermek olucak

Şu işinizi görür o zaman:

>>> import psutil
>>> memory = psutil.virtual_memory()
>>> gb = memory.free / 1024 ** 3

zaten bu şekilde kontrol sağlıyorum sorduğum olay şu uygun bellek miktarı olmadığı durumda komutu askıya almak ve uygun bellek boyutuna ulaşınca askıdan geri alıp çalıştırmak

Kodunuzu atmadığınıza göre en fazla algoritma verebilirim:

from time import sleep

while True:
    if yeterli_bellek_varmı():
        işleme_devam_et()
    sleep(1)

henüz bir algoritma oluşturamadığım için kodu yazmadım onun için atamıyorum kodu sadece kaynak kontrollerini yapabilecek kadar kod oluşturdum

İşlemi fonksiyonlara bölüp bu fonksiyonları bir listede toplayabilirsiniz. Daha sonra her seferinde listenin ilk elemanını silip o fonksiyonu çağırabilirsiniz.

Windows’ta olmadığını yeni öğrendim.

MemoryError hatası verme ihtimali olan kısmı try except içine alabiliyoruz. Ama işte asıl sorun Resource değişkenlerini setrlimit ile kontrol edebildiğimiz söyleniyor ama ben daha henüz belirlediğim limitlerin hangi birimlerde olduğunu anlayamadım. Python kaynağında diyor ki resource.RLIMIT_DATAnın int tipindeki limit değerleri bayt birimindendir. Oysa 8 bayt olarak belirlediğim sınırları aşan bir işlem yapılıyor, işlemin bir yerinde MemoryError yükseltiliyor ama limit rakamlarını değiştirdiğimde yine aynı i değerinde MemoryError hatası yükseltiliyor.

Evet toplamı geçiyor, mu soru işaretini yazmamışım. Evet bu 8 bayt toplam heap`i veriyor.

İyi de bu hatayı yakalayınca ne yapacağız? Demek istediğim işleme daha sonra kaldığımız yerden devam etmemizin zor olacağı. Bu yüzden burada kullanışsız dedim.

Zaten çalışacak uygulamayı @shigej38 yazmıyormuş, o sadece diğer uygulamaları yönetmek istiyor.

Anladım, o modül hakkında ayrıntılı bilgiye sahip değilim ama CPython’un ve işletim sisteminin arkada ne yaptığını tam olarak bilmiyoruz. O yüzden böyle ilginç davranışlarla karşılaşıyor olabiliriz.

Resource modülü yukarıda bahsettiğim sorunları vermeseydi, bu modülü kullanmayı önerebilirdim. Ama daha kaynakları kontrol etmek için yazılan rakamlar ile ana thread’de gerçekleşen işlem boyutunu istediğimiz gibi kontrol edemiyoruz.

1 Beğeni

Ama zaten biz şuan kendi uygulamamızın kapladığı hafıza ile ilgilenmiyoruz.