簡體   English   中英

"如何限制在 F# 中為異步 Seq.map 操作創建的線程數?"

[英]How to limit the number of threads created for an asynchronous Seq.map operation in F#?

當前的設置是這樣的

array
|> Seq.map (fun item -> async { return f item})
|> Async.Parallel
|> Async.RunSynchronously

如果要並行化將數組(或任何序列)作為輸入的CPU密集型計算,則最好使用F#PowerPack中的 PSeq模塊(盡管它僅在.NET 4.0中可用)。 它提供了許多標准Array.xyz函數的並行版本。 有關更多信息,您還可以查看帶有.NET示例的並行編程的 F#轉換

解決您的問題的代碼比使用工作流程要簡單一些:

array |> PSeq.map f
      |> PSeq.toArray 

兩種選擇之間的一些區別是:

  • PSeq是使用.NET 4.0中的任務並行庫(TPL)創建的,該庫經過優化可處理大量CPU密集型任務。
  • 異步在F#庫中實現,並在並發運行的操作中支持異步(非阻塞)操作,例如I / O。

總之,如果您需要異步操作(例如I / O),那么Async是最佳選擇。 如果您有大量的CPU密集型任務,那么PSeq可能是一個更好的選擇(在.NET 4.0上)

這是一個根據Brian的建議,如何使用信號量來執行此操作的示例:

open System

let throttle n fs =
    seq { let n = new Threading.Semaphore(n, n)
          for f in fs ->
              async { let! ok = Async.AwaitWaitHandle(n)
                      let! result = Async.Catch f
                      n.Release() |> ignore
                      return match result with
                             | Choice1Of2 rslt -> rslt
                             | Choice2Of2 exn  -> raise exn
                    }
        }

let f i = async { printfn "start %d" i
                  do! Async.Sleep(2000)
                }
let fs = Seq.init 10 f

fs |> throttle 2 |> Async.Parallel |> Async.RunSynchronously |> ignore

您可能會做幾件事。

首先,由於這使用了ThreadPool ,因此可以使用ThreadPool.SetMaxThreads

其次,您可以按照以下方式引入自己的節流閥:

let throttle = makeThrottle(8)
array 
|> Seq.map (fun item -> async { do! throttle.Wait()
                                return f item}) 
|> Async.Parallel 
|> Async.RunSynchronously 

makeThrottle()不會太難編寫,但是會產生一些同步開銷。 如果您試圖並行化太多事情以致內存不足,那么節流開銷很可能不是問題。 (如果您需要這種代碼的樣本,請告訴我。)

最后,如果這確實使事情崩潰了,它聞起來好像是您做錯了什么。 ThreadPool通常(但並非總是如此)在管理自身方面做得很好。 但是,在各種情況下,設計自己的節流閥對您的應用而言仍然很有價值。

自 2018 年拉取請求以來,F# Core 中有一個內置選項,通過Async.Parallel F# doc的第二次重載

array
|> Seq.map (fun item -> async { return f item})
|> fun computations -> Async.Parallel(computations, maxDegreeOfParallelism = 20)
|> Async.RunSynchronously

暫無
暫無

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

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