2014-04-30 5 views
6

मेरे पास एक बड़ी फाइलें हैं जहां मैं Binary डेटा स्टोर करता हूं। इन फ़ाइलों को पढ़ने और लिखने के कई धागे हैं, मेरा वर्तमान डिज़ाइन उन्हें एक Lock का उपयोग करके सिंक्रनाइज़ करता है। इस तरह, मेरे पास फ़ाइल के लिए ReadWriteMode में केवल एक Handle है, और सभी धागे उस एकल लॉक के लिए लड़ते हैं जब वे कुछ I/O करना पसंद करते हैं।समवर्ती फ़ाइल हास्केल में पढ़ती/लिखती है?

मैं एकाधिक पाठकों को समवर्ती रूप से काम करने की अनुमति देकर इस पर सुधार करना चाहता हूं। मैंने जो कोशिश की वह RWLock का उपयोग कर रहा था और कई हैंडल खुले थे। RWLock यह सुनिश्चित करेगा कि केवल एक थ्रेड फ़ाइल को संशोधित करता है, जबकि कई धागे (जितने मैंने खुले हैं, एक संकलन-समय निरंतर) को समवर्ती रूप से पढ़ने की अनुमति है। इसे चलाने की कोशिश करते समय, मुझे इस तथ्य से मारा गया कि रनटाइम allows only oneHandleReadWriteMode में किसी भी समय फ़ाइल के लिए मौजूद है।

मैं इस स्थिति को कैसे हल कर सकता हूं? मुझे लगता है कि Handle प्राप्त करने/जारी करने का एक महंगा ऑपरेशन है, इसलिए RWLock प्राप्त करने के बाद फ़ाइल को उचित मोड में खोलना वास्तव में एक विकल्प नहीं है। या शायद एक पैकेज है जो जावा FileChannel के read और write विधियों के समान एपीआई पेश करता है?

पीएस: मैं 32 बिट आर्किटेक्चर का समर्थन करना चाहता हूं, इसलिए स्मृति-मैप किए गए आईओ फाइलों के लिए संभव नहीं है> 4 जीआईबी, है ना?

+0

आप फ़ाइलों लेखन को पढ़ने के लिए किसी भी समानांतर आई/ओ लाइब्रेरी का उपयोग कर की कोशिश की? उनमें से कुछ हैं, एचडीएफ 5, पीएनईटीसीडीएफ, सियोनलिब ... वे सभी साझा और वितरित मेमोरी सिस्टम दोनों में समानांतर में फ़ाइलों को समवर्ती पढ़ने/लिखने का समर्थन करते हैं और वे सभी ओ (10^4) कोर तक बहुत अच्छे हैं । – gnzlbg

उत्तर

1

तो आपकी समस्या यह है कि आप राज्य के Handle एस (जहां राज्य फ़ाइल में वर्तमान स्थान है) का उपयोग नहीं करना चाहते हैं? उस स्थिति में, आपको लगता है कि आपको pread और pwrite की आवश्यकता है।

man pread

हास्केल के लिए बाध्यकारी: http://hackage.haskell.org/package/unix-bytestring-0.3.7.2/docs/System-Posix-IO-ByteString.html

एक उपयोग उदाहरण के लिए, आप यहाँ देख सकते हैं: https://github.com/errge/PrefetchFS/blob/master/PrefetchHandle.hs

+0

यह एकदम सही मैच की तरह दिखता है, मैं इसे जल्द ही कोशिश करूंगा। – Waldheinz

1

आपको फ़ाइल हैंडल और म्यूटेक्स लॉक के चारों ओर एक प्रकार का निर्माण करना चाहिए। यहां एक सरल कार्यान्वयन है जो मुझे लगता है कि आपके उद्देश्यों के लिए काम करेगा।

module SharedHandle (SharedHandle, newSharedHandle, withSharedHandle) where 

import Control.Concurrent.MVar 
import System.IO    

data SharedHandle = SharedHandle Handle (MVar()) 

newSharedHandle :: IO Handle -> IO SharedHandle 
newSharedHandle makeHandle = do 
    handle <- makeHandle 
    lock <- newMVar() 
    return $ SharedHandle handle lock 

withSharedHandle :: SharedHandle -> (Handle -> IO a) -> IO a 
withSharedHandle (SharedHandle handle lock) operation = do 
    () <- takeMVar lock 
    val <- operation handle 
    putMVar lock() 
    return val 

, उस पर क्या यहाँ पर कर रहा है मैं एक नया डेटाप्रकार है जो बना लिया है सार, बस एक फ़ाइल हैंडल है। केवल अंतर यह है कि यह एमवीआर के साथ लागू अपने स्वयं के व्यक्तिगत म्यूटेक्स लॉक के साथ भी आता है। मैंने इस नए प्रकार के संचालन के लिए दो कार्य प्रदान किए हैं। newSharedHandle एक ऑपरेशन लेता है जो एक सामान्य हैंडल बनाएगा और एक ताजा लॉक के साथ एक साझा हैंडल बनाया होगा। शेरडहैंडल हैंडल पर परिचालन के लिए एक ऑपरेशन लेता है, साझा हैंडल लॉक करता है, ऑपरेशन करता है, और फिर हैंडल को अनलॉक करता है। ध्यान दें कि कन्स्ट्रक्टर या एक्सेसर्स मॉड्यूल से उपलब्ध नहीं कराए जाते हैं, इसलिए हमें आश्वासन दिया जा सकता है कि लॉक को मुक्त करने के लिए कभी भी कोई प्रक्रिया भूल जाती है और हमें किसी विशेष पहुंच पर कभी भी डेडलॉक्स नहीं मिलते हैं।

इस नए प्रकार के साथ आपके प्रोग्राम में सभी फ़ाइल हैंडल को बदलने से आपकी समस्या हल हो सकती है।

+0

क्या यह बहुत कुछ नहीं है जो मैं पहले से कर रहा हूं? मैं नहीं देखता कि यह एकाधिक पाठकों को एक साथ काम करने की अनुमति देगा, क्योंकि वे एकल 'एमवर' के लिए सभी सामग्री (जो इस कोड में 'लॉक' के रूप में अधिक या कम उपयोग किया जाता है)। इसके अलावा, यह अपवाद-सुरक्षित नहीं है।;-) – Waldheinz

+0

मैंने सोचा था कि आप एक साथ कई फाइलें लिखना चाहते थे लेकिन व्यक्तिगत रूप से उन्हें लॉक करें ताकि पूरे सेट को एक साथ लॉक न किया जा सके। यदि आप वास्तव में एक ही समय में एक ही फाइल को लिखना चाहते हैं, तो क्या अनचाहे दौड़ की स्थिति रखने के लिए यह ठीक नहीं है? Posix पहले से ही आपको बिना किसी लॉकिंग के फ़ाइल में एकाधिक प्रक्रियाएं जोड़ने की अनुमति देता है। संक्षेप में, आपके प्रोग्राम में समस्या कुछ भी लॉक नहीं कर रही है और तेज प्रक्रिया को दौड़ जीतने और लिखने वाले पहले व्यक्ति होने में क्या समस्या है? – mmachenry

+0

ओह, शायद मुझे यह स्पष्ट रूप से कहा जाना चाहिए था: मेरी फ़ाइलें निश्चित आकार हैं और मैं फ़ाइल में यादृच्छिक ऑफसेट से लिख/पढ़ता हूं। मेरी समस्या सही ऑफ़सेट की तलाश करने और वास्तव में I/O करने के बीच की दौड़ है, जब एकाधिक थ्रेड एक फ़ाइल तक पहुंचते हैं। मेरे पास केवल दो फाइलें हैं, लेकिन पाठकों/लेखकों के दर्जनों। – Waldheinz

संबंधित मुद्दे