本文介绍了如何编写基于线程的并行列表迭代?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要作为一个例子,如何使用ocaml-threads编写并行iter函数。我的第一个想法是有一个与此类似的函数:

I need as an example how to program a parallel iter-function using ocaml-threads. My first idea was to have a function similiar to this:

let procs = 4 ;;

let rec _part part i lst =   match lst with
      [] -> ()
    | hd::tl ->
        let idx = i mod procs in
        (* Printf.printf "part idx=%i\n" idx; *)
        let accu = part.(idx) in
          part.(idx) <- (hd::accu);
          _part part (i+1) tl ;;

然后并行iter看起来像这样(这里是基于流程的变体):

Then a parallel iter could look like this (here as process-based variant):

let iter f lst =   let part = Array.create procs [] in
    _part part 0 lst;
    let rec _do i =
      (* Printf.printf "do idx=%i\n" i; *)
      match Unix.fork () with
          0 -> (* Code of child *)
            if i < procs then
              begin
                (* Printf.printf "child %i\n" i; *)
                List.iter f part.(i)
              end
        | pid -> (* Code of father *)
            (* Printf.printf "father %i\n" i; *)
            if i >= procs then ignore (Unix.waitpid [] pid)
            else _do (i+1)
    in
      _do 0 ;;

因为Thread-module的使用有点不同,我将如何使用ocaml的线程编写代码模块?

Because the usage of Thread-module is a little bit different, how would I code this using ocaml's thread module?

还有一个问题,_part()函数必须扫描整个列表,将它们分成n个部分,然后每个部分将通过每个自己的进程进行管道传输(这里)。还是存在一个没有先拆分列表的解决方案吗?

And there is another question, the _part() function must scan the whole list to split them into n parts and then each part will be piped through each own processes (here). Still exists there a solution without splitting a list first?

推荐答案

如果你有一个处理列表的函数,你想要独立地在几个列表上运行它,你可以使用该函数和每个列表调用 Thread.create 。如果您将列表存储在数组 part 中,那么:

If you have a function which processes a list, and you want to run it on several lists independently, you can call Thread.create with that function and every list. If you store your lists in array part then:

let threads = Array.map (Thread.create (List.iter f)) part in
Array.iter Thread.join threads

INRIA OCaml线程不是实际线程:在任何给定时间只执行一个线程,这意味着如果您有四个处理器和四个线程,则所有四个线程将使用相同的处理器,其他三个线程将保持未使用状态。

INRIA OCaml threads are not actual threads: only one thread executes at any given time, which means if you have four processors and four threads, all four threads will use the same processor and the other three will remain unused.

线程有用的地方是它们仍然允许异步编程:一些 Thread 模块原语可以等待外部资源变得可用。这可以减少软件被不可用资源阻止的时间,因为您可以让另一个线程同时执行其他操作。您还可以使用它来同时启动多个外部异步进程(例如通过HTTP查询多个Web服务器)。如果您没有很多与资源相关的阻止,这对您没有帮助。

Where threads are useful is that they still allow asynchronous programming: some Thread module primitives can wait for an external resource to become available. This can reduce the time your software spends blocked by an unavailable resource, because you can have another thread do something else in the mean time. You can also use this to concurrently start several external asynchronous processes (like querying several web servers through HTTP). If you don't have a lot of resource-related blocking, this is not going to help you.

至于列表拆分问题:访问元素列表,您必须遍历所有以前的元素。虽然这种遍历理论上可以分散在多个线程或进程中,但是通信开销可能会比在一个进程中提前分割事物慢得多。或使用数组。

As for your list-splitting question: to access an element of a list, you must traverse all previous elements. While this traversal could theoretically be split across several threads or processes, the communication overhead would likely make it a lot slower than just splitting things ahead of time in one process. Or using arrays.

这篇关于如何编写基于线程的并行列表迭代?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 06:01