2013-07-31 8 views
6

Ho letto diversi post simili su questo argomento, ma nessuno sembra aiutarmi direttamente. Se questo è effettivamente un post duplicato, per favore indirizzami al thread contenente la soluzione!OSError: [Errno 12] Impossibile allocare memoria da python subprocess.call

Sto salvando un mucchio di immagini e poi richiamando ffmpeg su di esse con subprocess.call. Lo faccio un certo numero di volte per raccolte di immagini diverse. Questo è fondamentalmente quello che sto facendo:

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

In isolamento funziona bene. Tuttavia, quando ho anche qualche altra elaborazione fatta prima di queste chiamate (non all'interno del ciclo, semplicemente tenendo i valori in memoria prima dell'inizio del ciclo), si blocca con un errore di memoria dopo aver realizzato diversi video (in realtà mentre stava facendo l'ultimo uno). Secondo this comment, subprocess.call forks/clona il processo corrente, il che sembra significare che richiede un'allocazione di memoria uguale a quanto ho attualmente in memoria, il che sembra essere eccessivo per quello che voglio fare chiamando ffmpeg.

Come posso chiamare ffmpeg da python senza chiedere di allocare quantità di memoria non necessarie?

risposta

3

Mentre è vero che subprocess.call esegue il fork del processo e questo processo figlio ha il proprio spazio di memoria che è inizialmente identico al processo padre (il programma python), i sistemi operativi moderni useranno lo copy-on-write memory. L'overhead di memoria del processo biforcuto è inizialmente relativamente piccolo, richiedendo solo pochi KB di memoria nel kernel per l'accounting di processo. Non è fino a quando quel processo figlio inizia ad apportare modifiche alla sua memoria che è necessaria memoria extra.

Dopo la foratura, il processo figlio generato da subprocess.call chiamerà una delle chiamate di sistema exec, che carica ffmpeg in memoria e avvia l'esecuzione.

Inoltre, fork è in genere l'unico meccanismo per creare un nuovo processo su un sistema POSIX (see here), quindi non penso che ci sia un'alternativa alla sequenza fork-then-exec che subprocess.call implementa.

Si può provare a eseguire il programma tramite strace o Valgrind per vedere esattamente quale chiamata di sistema non riceve la memoria richiesta. Questo può aiutare a determinare come ridurre i requisiti di memoria.

+0

risposta qui è consice e chiara: le forche processo parziali del processo e la memoria può aumentare. Ecco un altro Q & A SO coinvolto che potrebbe anche aiutare: http://stackoverflow.com/questions/1367373/python-subprocess-popen-oserror-errno-12-cannot-allocate-memory fornire maggiori dettagli a coloro che hanno questo problema – Paul

2

Ho avuto lo stesso problema di oggi e ho appena lavorato intorno ad esso utilizzando os:

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