2013-07-31 15 views
6

Czytałem kilka podobnych postów na ten temat, ale wydaje mi się, że nie pomagają mi bezpośrednio. Jeśli faktycznie jest to duplikat postu, proszę skieruj mnie do wątku zawierającego rozwiązanie!OSError: [Errno 12] Nie można przydzielić pamięci z python subprocess.call

Zapisuję garść obrazów, a następnie wywołuję na nich ffmpeg z podprocesorem. Robię to kilka razy dla kolekcji różnych obrazów. Zasadniczo to właśnie robię:

from subprocess import call 
for video in videos: 
    call(['ffmpeg', ..., '-i', video, video+'.mp4')]) 

W odosobnieniu to działa dobrze. Jednakże, gdy wykonuję również inne przetwarzanie przed tymi wywołaniami (nie w pętli, dosłownie po prostu utrzymywanie wartości w pamięci przed rozpoczęciem pętli), powoduje awarię z powodu błędu pamięci po wykonaniu kilku filmów (w rzeczywistości podczas robienia ostatniego jeden). Według this comment, subprocess.call widnieje/klonuje bieżący proces, co wydaje się oznaczać, że żąda alokacji pamięci równej temu, ile aktualnie mam w pamięci, co wydaje się być przesadą w stosunku do tego, co chcę zrobić w wywołaniu ffmpeg.

Jak mogę wywołać ffmpeg z poziomu Pythona bez pytania o przydzielenie niepotrzebnej ilości pamięci?

Odpowiedz

3

Podczas gdy prawdą jest, że podproces.call powoduje rozwidlenie procesu, a ten proces potomny ma własną przestrzeń pamięci, która jest początkowo identyczna z procesem nadrzędnym (program python), nowoczesne systemy operacyjne będą używać copy-on-write memory. Narzut pamięci procesu rozwidlonego jest początkowo względnie mały, wymagając jedynie kilku kilobajtów pamięci w jądrze do księgowania procesu. Dopiero proces potomny zaczyna wprowadzać zmiany w pamięci, że wymagana jest dodatkowa pamięć.

Proces potomny spawnowany przez subprocess.call wywoła jedno z wywołań systemowych exec, które wczytuje ffmpeg do pamięci i zacznie go wykonywać.

Co więcej, fork jest zwykle jedynym mechanizmem do stworzenia nowego procesu w systemie POSIX (see here), więc nie sądzę, że istnieje alternatywa dla sekwencji fork-then-exec, którą implementuje subprocess.call.

Możesz spróbować uruchomić swój program przez strace lub Valgrind, aby zobaczyć dokładnie, jakie wywołanie systemowe nie otrzymuje żądanej pamięci. Może to pomóc w określeniu, jak obniżyć wymagania dotyczące pamięci.

+0

Odpowiedź tutaj jest consice i jasne: widły podproces proces i pamięć może wzrosnąć. Oto bardziej zaangażowane pytania i odpowiedzi, które również mogą pomóc: http://stackoverflow.com/questions/1367373/python-subprocess-popen-oserror-errno-12- cannon-allocate-memory podaj więcej szczegółów tym, którzy mają ten problem – Paul

2

miałem ten sam problem dzisiaj i po prostu pracował wokół niego za pomocą OS:

import os 
for video in videos: 
    job = ' ffmpeg ' + ... + ' -i ' + video + '.mp4' 
    os.system(job) 
Powiązane problemy