标题可能有点模糊。这就是我的意思:
说我有两种获取输入方式的方法。第一种是通过键盘,使用函数getLine
阻塞直到读取一行。另一个是,例如,通过TChan
,其中使用readTChan chan
也将导致一个块,直到通道中存在一个值,然后它将被读取。
我想要完成的是能够等待两个值,使用单个线程并且不允许我的CPU跳转到100%。当两个值中的一个可用时,将获取它并重新启动程序。 (假设,使用Either
通知收到了两个值中的哪一个。)
这可能吗?
非常感谢!
答案 0 :(得分:12)
我不认为“使用单个线程”在这里有意义。您必须已经使用多个Haskell线程来写入TChan
。您应该使用两个Haskell线程来执行此操作,并使用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)
一个正确的实现可能会清理之后留下的线程,顺便说一句。
答案 1 :(得分:5)
我有两种获取输入程序的方法
你应该能够使用2个线程,每个输入源一个,等待各自的输入,将结果写入共享通道或mvar由第三个线程控制。
答案 2 :(得分:2)
hackage上的“async”包中有playerView.loadVideoWithId(videoId: "jCHE0Tjw6MA", playerVars: playerVars)
辅助函数。
同时运行两个IO操作,因此一个可能是race :: IO a -> IO b -> IO (Either a b)
,另一个可能是getLine
或其他阻止。返回MVar
,指示哪一个首先返回(另一个被取消)。
https://hackage.haskell.org/package/async-2.0.2/docs/Control-Concurrent-Async.html#v:race