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