加入的第一个成品线程? [英] Joining on the first finished thread?
问题描述
我写了一系列的F#图的搜索算法,并认为这将是很好的采取并行的优势。我想在并行执行多个线程,并采取第一个完成的结果。我有一个实现,但它不是pretty。
两个问题:是有这种功能的标准名称?没有加入或JoinAll,但JoinFirst?其次,有没有更地道的方式来做到这一点?
//执行
让makeAsync(柜:OBJ)(共享:一个选项REF)(F:单位 - >'一)=
异步{
让结果= F()
Monitor.Enter更衣室
共享:=有些结果
Monitor.Pulse更衣室
Monitor.Exit更衣室
}让firstFinished测试工作=
让结果= REF Option.None
让更衣室=新OBJ()
让取消=新CancellationTokenSource()
工作|> List.map(makeAsync更衣室结果)|> List.map(乐趣A-> Async.StartAsTask(一,TaskCreationOptions.None,cancel.Token))|>忽视
Monitor.Enter更衣室
而(result.Value.IsNone ||(而不是< |测试result.Value.Value))做
Monitor.Wait储物柜|>忽视
Monitor.Exit更衣室
cancel.Cancel()
匹配result.Value与
|一些X-> X
|无 - > failwith不要在空单通
//结束implentation//测试
让delayReturn(MS:INT)值=
有趣的() - >
Thread.sleep代码毫秒
值让试验(+)=
让工作= [delayReturn 1000第一! delayReturn 5000第二次! ]
让结果= firstFinished(FUN&_- GT;真)工作
printfn%S的结果
随着.NET 4任务并行库,这就是所谓的了WaitAny
。例如,下面的代码片段创建10个任务,并等待任何人来完成:
开放的System.ThreadingArray.init 10(FUN _ - >
Tasks.Task.Factory.StartNew(乐趣() - GT;
Thread.sleep代码1000))
|> Tasks.Task.WaitAny
I'm writing up a series of graph-searching algorithms in F# and thought it would be nice to take advantage of parallelization. I wanted to execute several threads in parallel and take the result of the first one to finish. I've got an implementation, but it's not pretty.
Two questions: is there a standard name for this sort of function? Not a Join or a JoinAll, but a JoinFirst? Second, is there a more idiomatic way to do this?
//implementation
let makeAsync (locker:obj) (shared:'a option ref) (f:unit->'a) =
async {
let result = f()
Monitor.Enter locker
shared := Some result
Monitor.Pulse locker
Monitor.Exit locker
}
let firstFinished test work =
let result = ref Option.None
let locker = new obj()
let cancel = new CancellationTokenSource()
work |> List.map (makeAsync locker result) |> List.map (fun a-> Async.StartAsTask(a, TaskCreationOptions.None, cancel.Token)) |> ignore
Monitor.Enter locker
while (result.Value.IsNone || (not <| test result.Value.Value)) do
Monitor.Wait locker |> ignore
Monitor.Exit locker
cancel.Cancel()
match result.Value with
| Some x-> x
| None -> failwith "Don't pass in an empty list"
//end implentation
//testing
let delayReturn (ms:int) value =
fun ()->
Thread.Sleep ms
value
let test () =
let work = [ delayReturn 1000 "First!"; delayReturn 5000 "Second!" ]
let result = firstFinished (fun _->true) work
printfn "%s" result
With the Task Parallel Library in .NET 4, this is called WaitAny
. For example, the following snippet creates 10 tasks and waits for any of them to complete:
open System.Threading
Array.init 10 (fun _ ->
Tasks.Task.Factory.StartNew(fun () ->
Thread.Sleep 1000))
|> Tasks.Task.WaitAny
这篇关于加入的第一个成品线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!