src/​examples/​cpp03/​spawn/​parallel_grep.​cppsrc/​examples/​cpp11/​spawn/​parallel_grep.​cpp
⋮⋮
1 /​/​1 /​/​
2 /​/​·​parallel_grep.​cpp2 /​/​·​parallel_grep.​cpp
3 /​/​·​~~~~~~~~~~~~~~~~~3 /​/​·​~~~~~~~~~~~~~~~~~
4 /​/​4 /​/​
5 /​/​·​Copyright·​(c)​·​2003-​2020·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​5 /​/​·​Copyright·​(c)​·​2003-​2020·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​
6 /​/​6 /​/​
7 /​/​·​Distributed·​under·​the·​Boost·​Software·​License,​·​Version·​1.​0.​·​(See·​accompanying7 /​/​·​Distributed·​under·​the·​Boost·​Software·​License,​·​Version·​1.​0.​·​(See·​accompanying
8 /​/​·​file·​LICENSE_1_0.​txt·​or·​copy·​at·​http:​/​/​www.​boost.​org/​LICENSE_1_0.​txt)​8 /​/​·​file·​LICENSE_1_0.​txt·​or·​copy·​at·​http:​/​/​www.​boost.​org/​LICENSE_1_0.​txt)​
9 /​/​9 /​/​
10 10
11 #include·​<asio/​dispatch.​hpp>11 #include·​<asio/​dispatch.​hpp>
12 #include·​<asio/​post.​hpp>12 #include·​<asio/​post.​hpp>
13 #include·​<asio/​spawn.​hpp>13 #include·​<asio/​spawn.​hpp>
14 #include·​<asio/​strand.​hpp>14 #include·​<asio/​strand.​hpp>
15 #include·​<asio/​thread_pool.​hpp>15 #include·​<asio/​thread_pool.​hpp>
16 #include·​<boost/​bind/​bind.​hpp>
17 #include·​<fstream>16 #include·​<fstream>
18 #include·​<iostream>17 #include·​<iostream>
19 #include·​<string>18 #include·​<string>
20 19
21 using·​asio:​:​dispatch;​20 using·​asio:​:​dispatch;​
22 using·​asio:​:​spawn;​21 using·​asio:​:​spawn;​
23 using·​asio:​:​strand;​22 using·​asio:​:​strand;​
24 using·​asio:​:​thread_pool;​23 using·​asio:​:​thread_pool;​
25 using·​asio:​:​yield_context;​24 using·​asio:​:​yield_context;​
26 25
27 void·​print_match(std:​:​string·​input_file,​·​std:​:​string·​line)​
28 {
29 ·​·​std:​:​cout·​<<·​input_file·​<<·​':​'·​<<·​line·​<<·​std:​:​endl;​
30 }
31
32 void·​search_file(std:​:​string·​search_string,​·​std:​:​string·​input_file,​
33 ·​·​·​·​strand<thread_pool:​:​executor_type>·​output_strand,​·​yield_context·​yield)​
34 {
35 ·​·​std:​:​ifstream·​is(input_file.​c_str()​)​;​
36 ·​·​std:​:​string·​line;​
37 ·​·​std:​:​size_t·​line_num·​=·​0;​
38 ·​·​while·​(std:​:​getline(is,​·​line)​)​
39 ·​·​{
40 ·​·​·​·​/​/​·​If·​we·​find·​a·​match,​·​send·​a·​message·​to·​the·​output.​
41 ·​·​·​·​if·​(line.​find(search_string)​·​!=·​std:​:​string:​:​npos)​
42 ·​·​·​·​{
43 ·​·​·​·​·​·​dispatch(output_stran​d,​·​boost:​:​bind(&print_match,​·​input_file,​·​line)​)​;​
44 ·​·​·​·​}
45
46 ·​·​·​·​/​/​·​Every·​so·​often·​we·​yield·​control·​to·​another·​coroutine.​
47 ·​·​·​·​if·​(++line_num·​%·​10·​==·​0)​
48 ·​·​·​·​·​·​post(yield)​;​
49 ·​·​}
50 }
51
52 int·​main(int·​argc,​·​char*·​argv[])​26 int·​main(int·​argc,​·​char*·​argv[])​
53 {27 {
54 ·​·​try28 ·​·​try
55 ·​·​{29 ·​·​{
56 ·​·​·​·​if·​(argc·​<·​2)​30 ·​·​·​·​if·​(argc·​<·​2)​
57 ·​·​·​·​{31 ·​·​·​·​{
58 ·​·​·​·​·​·​std:​:​cerr·​<<·​"Usage:​·​parallel_grep·​<string>·​<files.​.​.​>\n";​32 ·​·​·​·​·​·​std:​:​cerr·​<<·​"Usage:​·​parallel_grep·​<string>·​<files.​.​.​>\n";​
59 ·​·​·​·​·​·​return·​1;​33 ·​·​·​·​·​·​return·​1;​
60 ·​·​·​·​}34 ·​·​·​·​}
61 35
62 ·​·​·​·​/​/​·​We·​use·​a·​fixed·​size·​pool·​of·​threads·​for·​reading·​the·​input·​files.​·​The36 ·​·​·​·​/​/​·​We·​use·​a·​fixed·​size·​pool·​of·​threads·​for·​reading·​the·​input·​files.​·​The
63 ·​·​·​·​/​/​·​number·​of·​threads·​is·​automatically·​determined·​based·​on·​the·​number·​of37 ·​·​·​·​/​/​·​number·​of·​threads·​is·​automatically·​determined·​based·​on·​the·​number·​of
64 ·​·​·​·​/​/​·​CPUs·​available·​in·​the·​system.​38 ·​·​·​·​/​/​·​CPUs·​available·​in·​the·​system.​
65 ·​·​·​·​thread_pool·​pool;​39 ·​·​·​·​thread_pool·​pool;​
66 40
67 ·​·​·​·​/​/​·​To·​prevent·​the·​output·​from·​being·​garbled,​·​we·​use·​a·​strand·​to·​synchronise41 ·​·​·​·​/​/​·​To·​prevent·​the·​output·​from·​being·​garbled,​·​we·​use·​a·​strand·​to·​synchronise
68 ·​·​·​·​/​/​·​printing.​42 ·​·​·​·​/​/​·​printing.​
69 ·​·​·​·​strand<thread_pool:​:​executor_type>·​output_strand(pool.​get_executor()​)​;​43 ·​·​·​·​strand<thread_pool:​:​executor_type>·​output_strand(pool.​get_executor()​)​;​
70 44
71 ·​·​·​·​/​/​·​Spawn·​a·​new·​coroutine·​for·​each·​file·​specified·​on·​the·​command·​line.​45 ·​·​·​·​/​/​·​Spawn·​a·​new·​coroutine·​for·​each·​file·​specified·​on·​the·​command·​line.​
72 ·​·​·​·​std:​:​string·​search_string·​=·​argv[1];​46 ·​·​·​·​std:​:​string·​search_string·​=·​argv[1];​
73 ·​·​·​·​for·​(int·​argn·​=·​2;​·​argn·​<·​argc;​·​++argn)​47 ·​·​·​·​for·​(int·​argn·​=·​2;​·​argn·​<·​argc;​·​++argn)​
74 ·​·​·​·​{48 ·​·​·​·​{
75 ·​·​·​·​·​·​std:​:​string·​input_file·​=·​argv[argn];​49 ·​·​·​·​·​·​std:​:​string·​input_file·​=·​argv[argn];​
76 ·​·​·​·​·​·​spawn(pool,​·​boost:​:​bind(&search_file,​·​search_string,​50 ·​·​·​·​·​·​spawn(pool,​
77 ·​·​·​·​·​·​·​·​·​·​·​·​input_file,​·​output_strand,​·​boost:​:​placeholders:​:​_1)​)​;​51 ·​·​·​·​·​·​·​·​[=](yield_context·​yield)​
52 ·​·​·​·​·​·​·​·​{
53 ·​·​·​·​·​·​·​·​·​·​std:​:​ifstream·​is(input_file.​c_str()​)​;​
54 ·​·​·​·​·​·​·​·​·​·​std:​:​string·​line;​
55 ·​·​·​·​·​·​·​·​·​·​std:​:​size_t·​line_num·​=·​0;​
56 ·​·​·​·​·​·​·​·​·​·​while·​(std:​:​getline(is,​·​line)​)​
57 ·​·​·​·​·​·​·​·​·​·​{
58 ·​·​·​·​·​·​·​·​·​·​·​·​/​/​·​If·​we·​find·​a·​match,​·​send·​a·​message·​to·​the·​output.​
59 ·​·​·​·​·​·​·​·​·​·​·​·​if·​(line.​find(search_string)​·​!=·​std:​:​string:​:​npos)​
60 ·​·​·​·​·​·​·​·​·​·​·​·​{
61 ·​·​·​·​·​·​·​·​·​·​·​·​·​·​dispatch(output_stran​d,​
62 ·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​[=]
63 ·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​{
64 ·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​std:​:​cout·​<<·​input_file·​<<·​':​'·​<<·​line·​<<·​std:​:​endl;​
65 ·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​})​;​
66 ·​·​·​·​·​·​·​·​·​·​·​·​}
67
68 ·​·​·​·​·​·​·​·​·​·​·​·​/​/​·​Every·​so·​often·​we·​yield·​control·​to·​another·​coroutine.​
69 ·​·​·​·​·​·​·​·​·​·​·​·​if·​(++line_num·​%·​10·​==·​0)​
70 ·​·​·​·​·​·​·​·​·​·​·​·​·​·​post(yield)​;​
71 ·​·​·​·​·​·​·​·​·​·​}
72 ·​·​·​·​·​·​·​·​})​;​
78 ·​·​·​·​}73 ·​·​·​·​}
79 74
80 ·​·​·​·​/​/​·​Join·​the·​thread·​pool·​to·​wait·​for·​all·​the·​spawned·​tasks·​to·​complete.​75 ·​·​·​·​/​/​·​Join·​the·​thread·​pool·​to·​wait·​for·​all·​the·​spawned·​tasks·​to·​complete.​
81 ·​·​·​·​pool.​join()​;​76 ·​·​·​·​pool.​join()​;​
82 ·​·​}77 ·​·​}
83 ·​·​catch·​(std:​:​exception&·​e)​78 ·​·​catch·​(std:​:​exception&·​e)​
84 ·​·​{79 ·​·​{
85 ·​·​·​·​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​80 ·​·​·​·​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​
86 ·​·​}81 ·​·​}
87 82
88 ·​·​return·​0;​83 ·​·​return·​0;​
89 }84 }