Last active
September 3, 2015 02:50
-
-
Save ot32em/e677b9724af12859beb9 to your computer and use it in GitHub Desktop.
A brief usage of `sequential`, `thread`, `async`, `packaged_task`, and `promise`.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
#include <numeric> | |
#include <thread> | |
#include <chrono> | |
#include <random> | |
#include <future> | |
namespace tool | |
{ | |
std::vector<int> gen_vector(std::size_t s) | |
{ | |
std::random_device eng; | |
std::uniform_int_distribution<> gen(0, 100); | |
std::vector<int> vec(s); | |
std::generate(vec.begin(), vec.end(), [&]() { return gen(eng); }); | |
return vec; | |
} | |
std::chrono::milliseconds elapsed_ms(std::chrono::steady_clock::time_point tp) | |
{ | |
auto elapsed = std::chrono::steady_clock::now() - tp; | |
return std::chrono::duration_cast<std::chrono::milliseconds>(elapsed); | |
} | |
struct ScopeTimer | |
{ | |
using clock = std::chrono::steady_clock; | |
clock::time_point m_tp; | |
ScopeTimer(){ | |
std::cout << "Start calculating: " << std::endl; | |
m_tp = clock::now(); | |
} | |
~ScopeTimer(){ | |
const auto ms = elapsed_ms(m_tp).count(); | |
std::cout << "End of calculating: " << ms << " ms" << std::endl; | |
} | |
}; | |
} | |
int long_time_sum(const std::vector<int>& vec) | |
{ | |
std::this_thread::sleep_for(std::chrono::seconds(1)); | |
return std::accumulate(vec.begin(), vec.end(), 0, [](int a, int b) { | |
return a + b; | |
}); | |
} | |
void sequential(const std::vector<std::vector<int>>& src) | |
{ | |
tool::ScopeTimer timer; | |
for (const auto& vec : src) | |
{ | |
std::cout << long_time_sum(vec) << std::endl; | |
} | |
} | |
void concurrent_byref(const std::vector<std::vector<int>>& src) | |
{ | |
tool::ScopeTimer timer; | |
auto lambda = [](const std::vector<int>& vec, int& result) { | |
result = long_time_sum(vec); | |
}; | |
// Dispatch | |
std::vector<std::thread> ts; | |
std::vector<int> rets(src.size()); | |
for (std::size_t i = 0; i < src.size(); i++) | |
{ | |
ts.emplace_back(lambda, std::cref(src[i]), std::ref(rets[i])); | |
} | |
// Output | |
for (std::size_t i = 0; i < src.size(); i++) | |
{ | |
ts[i].join(); | |
std::cout << rets[i] << std::endl; | |
} | |
} | |
void concurrent_async(const std::vector<std::vector<int>>& src) | |
{ | |
tool::ScopeTimer timer; | |
// Dispatch | |
std::vector<std::future<int>> fs; | |
for (const auto& vec : src) | |
{ | |
fs.push_back(std::async(long_time_sum, std::cref(vec))); | |
} | |
// Output | |
for (auto& f : fs) | |
{ | |
std::cout << f.get() << std::endl; | |
} | |
} | |
void concurrent_packaged(const std::vector<std::vector<int>>& src) | |
{ | |
tool::ScopeTimer timer; | |
// Dispatch | |
std::vector<std::future<int>> fs; | |
for (const auto& vec: src) | |
{ | |
std::packaged_task<decltype(long_time_sum)> task(long_time_sum); | |
fs.push_back(task.get_future()); | |
std::thread(std::move(task), std::cref(vec)).detach(); | |
} | |
// Output | |
for (auto& f : fs) | |
{ | |
std::cout << f.get() << std::endl; | |
} | |
} | |
void concurrent_promise(const std::vector<std::vector<int>>& src) | |
{ | |
tool::ScopeTimer timer; | |
auto lambda = [](const std::vector<int>& vec, std::promise<int>& p) { | |
try { | |
auto ret = long_time_sum(vec); | |
p.set_value(ret); | |
} | |
catch (...) | |
{ | |
p.set_exception(std::current_exception()); | |
} | |
}; | |
// Dispatch | |
std::vector<std::promise<int>> ps(src.size()); | |
std::vector<std::future<int>> fs; | |
for (std::size_t i = 0; i < src.size(); i++) | |
{ | |
fs.push_back(ps[i].get_future()); | |
std::thread(lambda, std::cref(src[i]), std::ref(ps[i])).detach(); | |
} | |
// Output | |
for (auto& f : fs) | |
{ | |
std::cout << f.get() << std::endl; | |
} | |
} | |
int main() | |
{ | |
std::vector<std::vector<int>> src = { | |
tool::gen_vector(100), | |
tool::gen_vector(100), | |
tool::gen_vector(100), | |
tool::gen_vector(100) | |
}; | |
sequential(src); | |
concurrent_async(src); | |
concurrent_byref(src); | |
concurrent_packaged(src); | |
concurrent_promise(src); | |
std::cin.ignore(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment