| 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-2022·Christopher·M.·Kohlhoff·(chris·at·kohlhoff·dot·com) | 5 | //·Copyright·(c)·2003-2022·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/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_strand,·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 | ··try | 28 | ··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.·The | 36 | ····//·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·of | 37 | ····//·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·synchronise | 41 | ····//·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_strand, |
| | 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 | } |