2013-02-08 30 views
6

पर HTTP के माध्यम से क्यूटी स्ट्रीमिंग बड़ी फ़ाइल और एक बहुत ही स्मृति बाधित एम्बेडेड लिनक्स डिवाइस पर क्यूटी में अपने सर्वर पर HTTP के माध्यम से एक बड़ी फ़ाइल (1 जीबी) स्ट्रीम कर रहा हूं। जब मुझे पहले हेडर प्राप्त होता है तो मैं निर्धारित करता हूं कि फाइल सिस्टम पर डेटा कहां लिखना है, उस स्थान पर एक QFile सूचक बनाएं, और संलग्न करने के लिए फ़ाइल खोलें। सर्वर में एक 'संचित' फ़ंक्शन होता है जिसे प्रत्येक बार सॉकेट में नया डेटा आने पर बुलाया जाता है। उस संचित फ़ंक्शन से मैं लिखने के माध्यम से फ़ाइल को डेटा को स्ट्रीम करना चाहता हूं()। आप नीचे मेरे जमा समारोह देख सकते हैं।ईटीएमसी फ्लैश

यह समस्या करते समय मेरी समस्या स्मृति उपयोग है - मैं स्मृति से बाहर चला जाता हूं। क्या मुझे संचय के प्रत्येक पुनरावृत्ति() और fsync() को फ्लश करने में सक्षम नहीं होना चाहिए और राम उपयोग के बारे में चिंता करने की ज़रूरत नहीं है? मैं गलत क्या कर रहा हूं और मैं इसे कैसे ठीक कर सकता हूं? धन्यवाद -

मैं एक बार जमा समारोह से पहले अपने फ़ाइल को खोलने:

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

यहाँ संचित समारोह के एक हिस्से को है:

// 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 

संपादित करें:

मैं अपने कोड instrumented और 'waitForBytesWritten (-1)' कॉल हमेशा 'झूठी' वापस आती है। दस्तावेज़ों का कहना है कि यह तब तक इंतजार करना चाहिए जब तक कि डिवाइस पर डेटा लिखा न जाए।

इसके अलावा, अगर मैं केवल 'लिखने (डेटा)' लाइन को अपूर्ण करता हूं, तो मेरी मुफ्त मेमोरी कभी कम नहीं होती है। क्या चल रहा होगा? 'लिखने' कितनी मेमोरी का उपभोग करता है?

संपादित करें:

अब मैं निम्नलिखित कर रहा हूं। मैं स्मृति से बाहर नहीं चला हूं, लेकिन मेरी मुफ्त मेमोरी 2 एमबी तक गिर जाती है और पूरी फाइल स्थानांतरित होने तक वहां जाती है। उस बिंदु पर, स्मृति जारी की जाती है। यदि मैं बीच में स्थानांतरण को मारता हूं, तो कर्नेल स्मृति पर पकड़ता प्रतीत होता है क्योंकि यह प्रक्रिया को पुनरारंभ करने तक और उसी फ़ाइल को लिखने का प्रयास करने तक लगभग 2 एमबी मुक्त रहता है। मैं अब भी लगता है कि मैं का उपयोग करें और स्मृति प्रत्येक यात्रा फ्लश करने के लिए सक्षम होना चाहिए:

// 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 

संपादित करें:

लिनक्स कैशिंग गलतफहमी मेरे जैसे लगता है की इस तरह की। इस पोस्ट को पढ़ने के बाद ->http://blog.scoutapp.com/articles/2010/10/06/determining-free-memory-on-linux, यह संभव है कि मैं 'फ्री-एमटी' के आउटपुट को गलत समझ रहा हूं। मैं उस आउटपुट में 'फ्री' फ़ील्ड देख रहा हूं और बड़े पैमाने पर फाइल ट्रांसफर पर लगभग 2 एमबी होवर करने के लिए इसे छोड़ देता हूं। जब फ़ाइल स्थानांतरण किया जाता है तो मैं इसे मुफ्त डेटा के उच्च स्तर पर वापस देखना चाहूंगा।

+0

यह किस माह में चल रहा है? क्या यह एक सीजीआई ऐप है? – Jay

+0

यह एक एम्बेडेड लिनक्स पर्यावरण में चल रहा क्यूटी एम्बेडेड है। सर्वर पूरी तरह से क्यूटी/सी ++ में है और पोर्ट 80 पर सुनता है। – PhilBot

+0

यह कौन सा क्यूटी संस्करण है? लिखने/प्रतीक्षा के वापसी मूल्यों की जांच करेंफॉरबाइट्स लिखित/फ्लश (और यह भी खुला है, लेकिन यह असंबंधित है)। –

उत्तर

1

मुझे लगता है कि लिनक्स सिर्फ यह सब कुछ कैश कर रहा है और इसे 2 एमबी मुक्त मेमोरी सीमा के आसपास छोड़ सकता है। 512 एमबी रैम सिस्टम पर ~ 2 जीबी फाइलें प्राप्त करने या भेजने के दौरान मैं स्मृति से बाहर नहीं हूं। मेरे क्यूटी कार्यक्रम में, सभी डेटा प्राप्त करने, फ़ाइल में शामिल होने और फ़ाइल को बंद करने के बाद। मैं एक अलग टर्मिनल में 'फ्री-एमटी' कमांड में अपनी 'फ्री' मेमोरी रिटर्न देखने के लिए एक क्यूप्रोसेस में निम्नलिखित करता हूं:

// 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

समान समस्या उत्पन्न हुई ...हमारे मामले में, हमारे ऐप को थोड़ी देर के लिए ओएस (और उत्तरदायी नहीं) द्वारा निलंबित कर दिया जाता है जब रैम दांतों और इनोड्स से भरा हो जाता है (मुझे लगता है कि ओएस डिस्क पर कैश किए गए डेटा को फ्लश करता है)। बस fyi, 'sync && sysctl -w vm.drop_caches = 2' का भी उपयोग किया जा सकता है। – mBardos