2010-01-11 11 views
8

शीर्षक थोड़ा अस्पष्ट हो सकता है। मेरा यही मतलब है:हास्केल में दो इनपुटों की प्रतीक्षा, साथ ही

कहें कि मेरे पास मेरे प्रोग्राम में इनपुट प्राप्त करने के दो तरीके हैं। पहला, कीबोर्ड getLine का उपयोग करके कुंजीपटल के माध्यम से होता है जो लाइन को पढ़े जाने तक ब्लॉक करता है। दूसरा, TChan के माध्यम से कहता है, जहां readTChan chan का उपयोग करके एक ब्लॉक में परिणाम होगा जब तक कि चैनल में कोई मान मौजूद न हो, जहां इसे पढ़ा जाएगा।

जो मैं पूरा करना चाहता हूं वह दोनों मानों का उपयोग कर एक थ्रेड का उपयोग करके और मेरे सीपीयू को 100% तक पहुंचने की अनुमति नहीं दे रहा है। पल दो मानों में से एक उपलब्ध है, यह प्राप्त किया जाता है और कार्यक्रम फिर से शुरू होता है। (Either का उपयोग करके सूचित करें कि दो मानों में से कौन सा मूल्य प्राप्त हुआ था।)

क्या यह संभव है?

बहुत बहुत धन्यवाद!

+1

कैसे एक आईओ-धागा कॉल getLine होने, और साथ ही Tchan में उसके परिणाम डाल के बारे में? मुझे लगता है जैसे यह काम करना चाहिए .. – yairchu

+0

आप एक धागे का उपयोग क्यों करना चाहते हैं? क्या होगा, उदाहरण के लिए, आप 3 इनपुट के लिए इंतजार करना चाहते हैं? या 5? या 10? मनमानी प्रतिबंध क्यों? – ADEpt

+0

मुझे लगता है कि आपके पास कुछ कोड है जहां एकाधिक धागे उपयोग में थे और आपके पास 100% CPU था? आप कोड पोस्ट करना चाहते हैं ताकि अन्य लोग देख सकें कि क्यों: सही समाधान धागे है और यह केवल एक कार्यान्वयन समस्या हो सकती है। – Godeke

उत्तर

12

मुझे नहीं लगता कि "एक धागे का उपयोग करके" यहां समझ में आता है। TChan पर लिखने के लिए आपको पहले से ही कई हास्केल थ्रेड का उपयोग करना होगा। ऐसा करने के लिए आपको दो हास्केल थ्रेड का उपयोग करना चाहिए, और MVar या आने वाले पहले परिणाम को संवाद करने के समान ही उपयोग करना चाहिए। उदाहरण के लिए:

module Main where 

import System.IO 
import Control.Concurrent 
import Control.Concurrent.MVar 
import Control.Concurrent.STM 
import Control.Concurrent.STM.TChan 

main = do 
    chan <- newTChanIO 
    forkIO (threadTChanWrite chan) 
    threadMultiplexedRead chan 

threadTChanWrite chan = do 
    threadDelay 5000000 
    atomically $ writeTChan chan 3 

threadMultiplexedRead chan = do 
    mvar <- newEmptyMVar 
    forkIO (threadKeyboardRead mvar) 
    forkIO (threadTChanRead mvar chan) 
    v <- readMVar mvar 
    print v 

threadKeyboardRead mvar = do 
    str <- getLine 
    putMVar mvar (Right str) 

threadTChanRead mvar chan = do 
    v <- atomically (readTChan chan) 
    putMVar mvar (Left v) 

एक उचित कार्यान्वयन शायद ऊपर धागे साफ होता है, btw बाद में चारों ओर झूठ बोल छोड़ दिया।

5

मैं अपने कार्यक्रम के लिए इनपुट प्राप्त करने की दो तरीके हैं

आप, 2 सूत्र, इनपुट स्रोत प्रति एक है, जो अपने-अपने इनपुट पर इंतजार उपयोग करने के लिए सक्षम होना चाहिए एक साझा चैनल में परिणाम लेखन या एक तीसरे धागे द्वारा शासित mvar।

+0

-1: आपने अनदेखा किया कि कैसे क्यू एकल-थ्रेडेड सोलन के लिए पूछता है। –

+3

@ चार्ल्स आप बिंदु खो रहे हैं। यह एक से अधिक धागे का उपयोग न करने के लिए व्यर्थ है, और लड़का यह भी कहने में विफल रहता है कि क्यों। – Rayne

+3

उसे यह कहने की ज़रूरत नहीं है कि क्यों, और मैं नहीं देखता कि हम कैसे जानते हैं कि इच्छा व्यर्थ है। –

1

हैकेज पर "async" पैकेज में race :: IO a -> IO b -> IO (Either a b) सहायक फ़ंक्शन है।

एक साथ दो आईओ क्रियाएं चलाता है, इसलिए कोई भी getLine और अन्य MVar या जो कुछ भी हो सकता है। एक Either देता है जो दर्शाता है कि कौन सा पहले लौटा है (दूसरा रद्द कर दिया गया है)।

https://hackage.haskell.org/package/async-2.0.2/docs/Control-Concurrent-Async.html#v:race

+1

आईएमओ यह सही उत्तर है।स्वीकार्य उत्तर अत्यधिक जटिल है और यह उत्तर उस कार्यप्रणाली को निष्पादित करता है जो स्वीकार्य उत्तर कहता है। आपके पास 'async' के बजाय 'फोर्कियो' का उपयोग करने का एक अच्छा कारण होना चाहिए। –

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