Dün gece otomasyon sistemimin son halini test ediyordum. Ana koordinatör script'im master_runner.py, sırayla birkaç alt işlemi subprocess.call() ile çalıştırıyordu. Her şey güllük gülistanlıktı, ta ki data_processor adlı o lanet C++ binary'si çalışıncaya kadar.
Terminalde ana script'in çıktılarını izliyorum. İlk iki işlem tamam, sıra üçüncüde. Script şu satırı çalıştırdı:
Python:
subprocess.call(['./data_processor', 'input.bin'])
subprocess.call() güvenilir bir arkadaştır, ama çocuk sürecin (child process) her şeyini bekler. O süreç segfault ile ölürse ve bu işletim sistemi seviyesinde bir çöküşse, bazı durumlarda call() o sinyali doğru işleyemez ve takılır kalır. StackOverflow'da bile benim durumuma tam uyan bir çözüm bulamadım, şaka gibi.
İsyanımı bitirip kodu yeniden yazdım. Artık subprocess.Popen() kullanıyorum ve çıktıyı communicate() ile okuyorum. Daha da önemlisi, bir timeout parametresi ekledim. Şimdi kodum şöyle bir şeye benziyor:
Python:
try:
proc = subprocess.Popen(['./data_processor', 'input.bin'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate(timeout=30) # 30 saniye bekler, geçerse öldürür.
except subprocess.TimeoutExpired:
proc.kill()
print("Vah vah, işlem takıldı. Muhtemelen segfault!")
Siz de böyle bir "ölümcül bekleyiş" yaşadınız mı? subprocess.call() yerine hangi yöntemleri tercih ediyorsunuz? Ya da segfault'ları Python'dan yakalamanın daha temiz bir yolu var mı?