2011-08-31 19 views
8
में MVAr उदाहरण समझने

मैं GHC latest docs में MVAr उदाहरण समझने की कोशिश कर रहा हूँ -सहायता हास्केल

  1. putSkipChan जैसे कार्य कर रहे हैं -

    data SkipChan a = SkipChan (MVar (a, [MVar()])) (MVar()) 
    
    newSkipChan :: IO (SkipChan a) 
    newSkipChan = do 
        sem <- newEmptyMVar 
        main <- newMVar (undefined, [sem]) 
        return (SkipChan main sem) 
    
    putSkipChan :: SkipChan a -> a -> IO() 
    putSkipChan (SkipChan main _) v = do 
        (_, sems) <- takeMVar main 
        putMVar main (v, []) 
        mapM_ (sem -> putMVar sem()) sems 
    
    getSkipChan :: SkipChan a -> IO a 
    getSkipChan (SkipChan main sem) = do 
        takeMVar sem 
        (v, sems) <- takeMVar main 
        putMVar main (v, sem:sems) 
        return v 
    
    dupSkipChan :: SkipChan a -> IO (SkipChan a) 
    dupSkipChan (SkipChan main _) = do 
        sem <- newEmptyMVar 
        (v, sems) <- takeMVar main 
        putMVar main (v, sem:sems) 
        return (SkipChan main sem) 
    

    मैं कार्यक्रम का सबसे समझते हैं लेकिन दो प्रश्नों के लिए परमाणु? ऐसा लगता है कि पहले takeMVar कर putMVar पर अवरुद्ध होने से बचें। लेकिन takeMVar के बाद putMVar के बाद putMVar पर कुछ और कॉल करने में विफल नहीं होगा? ऐसे मामलों में, ऐसा लगता है कि कार्यक्रम हमेशा के लिए ब्लॉक होगा।

  2. dupSkipChansemSkipChan में सेमफोरों की सूची में क्यों संलग्न करता है? ऐसा नहीं है getSkipChan द्वारा किया गया है। ऐसा लगता है कि dupSkipChan पर getSkipChan (जो आपको लगता है कि है, तो एकाधिक पाठक होने के लिए) putSkipChan एक ही सेमफोर को दो बार उठाने का प्रयास करता है?

उत्तर

5
  1. आप सही हैं, एक और धागा putMVar main और गंदगी putSkipChan कह सकते हैं। लेकिन उपर्युक्त कोड बनाने वाला मॉड्यूल SkipChan कन्स्ट्रक्टर निर्यात नहीं करेगा, इसलिए इस तरह का एक दुष्ट ऑपरेशन असंभव होगा।

  2. dupSkipChan एक नईemptyMVar बुलाया sem बनाता है और कि कहते हैं मुख्य में सूची में। यह newSkipChan में बनाए गए पूर्व-मौजूदा को जोड़ता नहीं है। इस प्रकार कोई ब्लॉक नहीं है।

इस प्रश्न और टिप्पणी के अन्य पाठकों को और अधिक समझाएं: विचार यह है कि कई पाठक धागे हो सकते हैं। प्रारंभ में SkipChan main sem1 एकमात्र ऐसा पाठक है। dupSkipChanSkipChan main sem2 बनाता है। यदि हजारों पाठक हैं तो आप putSkipChan में नए मान के सभी को सूचित नहीं करना चाहते हैं, इस प्रकार डिज़ाइन यह है कि getSkipChan इसकी सेम को सूची में मुख्य रूप से रखता है। SkipChan को newSkipChan और dupSkipChan में किए गए आरंभ में मुख्य में सूची में नया खाली sem डालने में भी शामिल है।

उपरोक्त प्रारंभिकरण और डिज़ाइन का अर्थ है कि पहले getSkipChan को लिखा गया सबसे हालिया पिछले मान प्राप्त होता है (या आने वाले पहले मान के लिए ब्लॉक)। भविष्य getSkipChan उस SkipChan पर पहले से प्राप्त किसी भी नए मूल्य से हमेशा एक नया मान प्राप्त होगा, और यदि यह मान पहले से ही उपलब्ध है तो यह ब्लॉक नहीं करेगा।