Haskell 工作池

Haskell Job Pool

我对 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 代码?

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

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

下面我使用 MVar 等待后台处理程序退出。这就像一个常规的可变变量,但它受互斥锁保护。它可以是空的(只允许 put,等待 takes)或满的(只允许 take,等待 puts)。

我还在下面使用 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