簡體   English   中英

並行或多線程運行haskell操作

[英]run haskell operations in parallel or multithreaded

我剛剛開始學習函數式編程和Haskell,我甚至還不了解語法及其工作方式,因為它與我以前使用過的語法(例如,ruby,php,C#或node,它們是OOP)有很大的不同。語言-或多或少)。

我試圖將一個小程序組合在一起,以檢查Brocard問題的解決方案或所謂的Brown Numbers ,我首先用紅寶石創建了草稿,但是我發現Haskell更適合於做數學表達式。 我之前曾問過一個問題,並且很快就將紅寶石代碼轉換為Haskell得到了答案:

results :: [(Integer, Integer)] --Use instead of `Int` to fix overflow issue
results =  [(x,y) | x <- [1..1000], y <- [1..1000] , 1 + fac x == y*y]
    where fac n = product [1..n]

我稍作更改,因此我可以一直執行相同的操作,直到我想要的任何數字,因為上面的操作可以從11000或任何硬編碼的數字進行,但是我希望能夠確定應該經歷的時間間隔,因此:

pairs :: (Integer, Integer) -> [(Integer, Integer)]
pairs (lower, upper) =  [(m, n) | m <- [lower..upper], n <- [lower..upper], 1 + factorial n == m*m] where factorial n = product [1..n]

我問這個問題的原因是我在考慮是否可以並行(和/或在多個線程和/或內核上)運行此操作並將結果附加到同一變量中。

我尚未了解Haskell或線程模型中的並行處理,但是在ruby中,線程模型如何工作的一個很好的例子是這樣的

def func1
  i=0
  while i<=2
    puts "func1 at: #{Time.now}"
    sleep(2)
    i=i+1
  end
end

def func2
  j=0
  while j<=2
    puts "func2 at: #{Time.now}"
    sleep(1)
    j=j+1
  end
end

puts "Started At #{Time.now}"
t1=Thread.new{func1()}
t2=Thread.new{func2()}
t1.join
t2.join
puts "End at #{Time.now}"

在我的情況下, func1func2將是在不同時間間隔( [1..1000] -> [i..j] )上計算出的相同函數results

我很樂意為此提供一些幫助,因為我目前無法自己做:)

Haskell中的並行和並發編程有很多很好的信息,而異步是一個很好的庫。

不過,在最底層,您會發現forkIO啟動一個新的輕量級線程。

當然,這是並發的 ,而不是確定性的並行性, parallel是該類的庫,並且在本書中也進行了介紹。

您的示例轉換為:

import Data.Time.Clock (getCurrentTime)

main = do
    start <- getCurrentTime
    putStr "Started At " >> print start
    _ <- forkIO func1
    _ <- forkIO func2
    end <- getCurrentTime
    putStr "End at " >> print end

func1 = helper "func1" 2

func2 = helper "func2" 1

helper name sleepTime = go 0
 where
    go 3 = return ()
    go n = do
        now <- getCurrentTime
        putStr name >> putStr " at: " >> print now
        threadDelay sleepTime
        go $ succ n

但是,我建議學習上述並行和/或異步庫,而不是至少在最初時編寫自己的線程東西。

這是一個不太好的示例,使用並行在8-ish處理器上運行測試:

import Control.Parallel.Strategies

factorial = product . enumFromTo 1
pairs (lower, upper) =  map fst . filter snd . withStrategy sparkTest
                     $ [ ((m, n), b)
                       | m <- [lower..upper]
                       , n <- [lower..upper]
                       , let b = 1 + factorial n == m*m
                       ]
sparkTest = evalBuffer 8 $ evalTuple2 rseq rpar

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM