2017-03-04 40 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