2017-03-04 93 views
0

我对Haskell编程感兴趣,但我想创建一个工作池系统​​,并且我想知道这是否会成为Haskell中的问题。Haskell工作池

以下是Ruby中的一个简单程序。在执行的一个线程中,单词来自用户并添加到列表中。在另一个线程中,单词从列表中取出并以某种方式处理(在这种情况下,反转并打印回用户)。

words = [] 

# Create new thread to take words from array, one at a time, and process them 
t = Thread.new { 
    loop do 
    unless words.empty? 
     word = words.pop 
     break if word == 'quit' 
     sleep 1 
     puts word.reverse 
    end 
    end 
} 

# Take words from user and add to array 
loop do 
    puts "Enter word:" 
    word = gets.chomp 
    words << word 
    break if word == 'quit' 
end 

t.join 

什么是等价的Haskell代码?

回答

3

这是一个非常接近的翻译。

Chan是一个消息在Haskell线程之间传递的FIFO队列。

下面我使用MVar来等待假脱机程序退出。这就像一个常规的可变变量,但它受到互斥体的保护。它可以是空的(只允许puttake等待)或全部(只允许takeput等待)。

我还使用下面的Haskell线程,它可能在单独的OS级别的线程上运行 - Haskell运行时选择它。与OS线程相比,Haskell线程非常便宜。

参见例如Real World Haskell有关更多讨论。

{-# OPTIONS -Wall #-} 
module JobPool where 

import Control.Monad (when) 
import Control.Concurrent 

spooler :: Chan String -> MVar() -> IO() 
spooler ch stop = do 
    word <- readChan ch 
    if word == "quit" 
    then putMVar stop() 
    else do 
     threadDelay 1000000 -- us 
     putStrLn (reverse word) 
     spooler ch stop 

main :: IO() 
main = do 
    stop <- newEmptyMVar 
    ch <- newChan 
    _ <- forkIO $ spooler ch stop 
    let loop = do 
      word <- getLine 
      writeChan ch word 
      when (word /= "quit") loop 
    loop 
    takeMVar stop 
+2

'forkOS'不会提供新的操作系统线程。从这个意义上来说,它的命名很差。 'forkOS'唯一的区别在于它保证来自新线程的所有FFI调用都来自相同的本地线程。它没有提到在该本地线程上运行的其他haskell代码。 – Carl

+0

@chi谢谢。将“后台处理程序”功能与单词一起添加到通道,然后在新线程中,具有将较低级别函数(“后台打印程序”)应用于字? –

+1

@VorpulusLyphane我不确定我是否完全理解,但是如果您制作了自己的作品,则可以通过IO操作。陈(IO())'。通过这种方式,假脱机程序线程可以获取操作并运行它。你可以'writeChan ch(打印1;打印2)'并且数字将被后台打印程序线程使用类似'do act < - readChan ch;行动' – chi