加入的第一个成品线程? [英] Joining on the first finished thread?

查看:94
本文介绍了加入的第一个成品线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一系列的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆