-
Notifications
You must be signed in to change notification settings - Fork 0
/
cat.exs
68 lines (56 loc) · 1.63 KB
/
cat.exs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
defmodule CatFinder do
def cat(scheduler) do
send scheduler, { :ready, self }
receive do
{ :perform, filename, client } ->
send client, { :answer, filename, find_cats(filename), self }
cat(scheduler)
{ :shutdown } -> exit(0)
end
end
defp find_cats(filename) do
File.read!(filename)
|> :binary.matches("cat")
|> length
end
end
defmodule Scheduler do
def run(num_processes, module, func, to_calculate) do
(1..num_processes)
|> Enum.map(fn(_) -> spawn(module, func, [self]) end)
|> schedule_processes(to_calculate, [])
end
defp schedule_processes(processes, queue, results) do
receive do
{ :ready, pid } when length(queue) > 0 ->
[ next | tail ] = queue
send pid, { :perform, next, self }
schedule_processes(processes, tail, results)
{ :ready, pid } ->
send pid, { :shutdown }
if length(processes) > 1 do
schedule_processes(List.delete(processes, pid), queue, results)
else
Enum.sort(results, fn {n1, _}, {n2, _} -> n1 <= n2 end)
end
{ :answer, number, result, _pid } ->
schedule_processes(processes, queue, [ {number, result} | results ])
end
end
end
to_process = Enum.map(
File.ls!("/usr/local/share/man/man3"),
fn (name) ->
"/usr/local/share/man/man3/#{name}"
end
)
Enum.each 1..10, fn num_processes ->
{time, result} = :timer.tc(
Scheduler, :run, [num_processes, CatFinder, :cat, to_process]
)
if num_processes == 1 do
IO.inspect result
IO.puts "\n # time (s)"
end
:io.format "~2B ~.2f~n", [num_processes, time/1000000.0]
end