2013-02-08 9 views
6

Przesyłam duży plik (1 Gb) przez HTTP do mojego serwera w Qt na bardzo osadzonym w pamięci urządzeniu z systemem Linux. Kiedy po raz pierwszy otrzymam nagłówek, ustalam, gdzie zapisać dane w systemie plików, utwórz wskaźnik QFile do tej lokalizacji i otwórz plik do dołączenia. Na serwerze jest funkcja "akumuluj", która jest wywoływana za każdym razem, gdy nowe dane docierają do gniazda. Z tej funkcji gromadzenia chcę przesyłać dane bezpośrednio do pliku poprzez write(). Poniżej możesz zobaczyć moją funkcję akumulacji.Qt Przesyłanie strumieniowe dużego pliku za pośrednictwem HTTP i przepłukiwanie do eMMC Flash

Moim problemem jest użycie pamięci podczas wykonywania tej czynności - zabrakło mi pamięci. Czy nie powinienem móc przepłukać() i fsync() każdej iteracji akumulacji i nie martwić się o użycie pamięci RAM? Co robię źle i jak mogę to naprawić? Dzięki -

otwieram plik kiedyś funkcję akumuluj:

// Open the file 
filePointerToWriteTo->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Unbuffered) 

Oto część funkcji akumuluj:

// Extract the QFile pointer from the QVariant 
QFile *filePointerToWriteTo = (QFile *)(containerForPointer->pointer).value<void *>(); 

qDebug() << "APPENDING bytes: " << data.length(); 

// Write to the file and sync 
filePointerToWriteTo->write(data); 
filePointerToWriteTo->waitForBytesWritten(-1); 
filePointerToWriteTo->flush(); // Flush 
fsync(filePointerToWriteTo->handle()); // Make sure bytes are written to disk 

EDIT:

I oprzyrządowanie mój kod i wywołanie "waitForBytesWritten (-1)" ZAWSZE zwraca "false". Dokumenty mówią, że powinno to poczekać, aż dane zostaną zapisane na urządzeniu.

Ponadto, jeśli odkomentuję tylko linię "zapis (dane)", wtedy moja wolna pamięć nigdy nie spadnie. Co może się dziać? W jaki sposób "pisać" zużywa tyle pamięci?

EDYTOWANIE:

Teraz robię co następuje. Nie zabrakło mi pamięci, ale moja wolna pamięć spadła do 2 Mb i wisi tam, dopóki cały plik nie zostanie przesłany. W tym momencie pamięć zostaje zwolniona. Jeśli zabijam transfer w środku, wydaje mi się, że jądro zatrzymuje się w pamięci, ponieważ pozostaje wolne około 2 MB, dopóki nie zrestartuję procesu i spróbuję napisać do tego samego pliku. Nadal uważam, że powinienem być w stanie wykorzystać i opróżnić pamięci każdej iteracji:

// Extract the QFile pointer from the QVariant 
QFile *filePointerToWriteTo = (QFile *)(containerForPointer->pointer).value<void *>(); 

int numberOfBytesWritten = filePointerToWriteTo->write(data); 
qDebug() << "APPENDING bytes: " << data.length() << " ACTUALLY WROTE: " << numberOfBytesWritten; 

// Flush and sync 
bool didWaitForWrite = filePointerToWriteTo->waitForBytesWritten(-1); // <----------------------- This ALWAYS returns false! 
filePointerToWriteTo->flush(); // Flush 
fsync(filePointerToWriteTo->handle()); // Make sure bytes are written to disk 
fdatasync(filePointerToWriteTo->handle()); // Specific Sync 
sync(); // Total sync 

EDIT:

Ten rodzaj dźwięków takich jak ja nieporozumienie buforowanie Linux. Po przeczytaniu tego posta ->http://blog.scoutapp.com/articles/2010/10/06/determining-free-memory-on-linux, możliwe jest, że nie rozumiem wyniku "free -mt". Oglądałem "wolne" pole w tym pliku wyjściowym i widziałem, jak spada do poziomu około 2 MB na masowym przesyłaniu plików. Po prostu chciałbym, aby powrócił do wysokiego poziomu darmowych danych po zakończeniu przesyłania plików.

+0

W jakim środowisku to działa? Czy to jest aplikacja cgi? – Jay

+0

To Qt Embedded działa w środowisku Embedded Linux. Serwer jest w całości w Qt/C++ i nasłuchuje na porcie 80. – PhilBot

+0

Która wersja Qt to jest? Sprawdź zwracane wartości write/waitForBytesWritten/flush (a także otwórz, ale to nie ma związku). –

Odpowiedz

1

Myślę, że Linux po prostu buforuje wszystko, co może i zwalnia to, co może zaoszczędzić około 2 MB wolnego limitu pamięci. Nie zabrakło mi pamięci podczas odbierania lub wysyłania ~ 2 GB plików w 512 MB systemie RAM. W moim programie Qt, po otrzymaniu wszystkich danych, dołączeniu do pliku i zamknięciu pliku. Wykonuję następujące czynności w QProcess, aby sprawdzić, czy moja wolna pamięć powraca w poleceniu "free -mt" w oddzielnym terminalu:

// Now we've returned a large file - so free up cache in linux 
QProcess freeCachedMemory; 
freeCachedMemory.start("sh"); 
freeCachedMemory.write("sync; echo 3 > /proc/sys/vm/drop_caches"); // Sync to disk and clear Linux cache 
freeCachedMemory.waitForFinished(); 
freeCachedMemory.close(); 
+0

Wystąpił ten sam problem ...W naszym przypadku nasza aplikacja jest zawieszona przez system operacyjny (i nie reaguje) przez pewien czas, gdy pamięć RAM jest pełna z denterami i i-węzłami (zakładam, że system operacyjny opróżni buforowane dane na dysk). Tylko fyi, można również użyć opcji 'sync && sysctl -w vm.drop_caches = 2'. – mBardos

Powiązane problemy