diff --git a/basic_content/concurrency/README.md b/basic_content/concurrency/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ac3acc518de9e08a8c3c2fa8a93c40f96422e37d --- /dev/null +++ b/basic_content/concurrency/README.md @@ -0,0 +1,9 @@ +## C++ concurrency program + +1. Multithreaded sorting +2. Thread-safe data structures + - Thread-safe queue + - Thread-safe stack + - ... +3. Hierarchical mutex +4. To be added... \ No newline at end of file diff --git a/basic_content/concurrency/main.cpp b/basic_content/concurrency/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2d95b0d968ef8b6bb3882f33064efc37ce9d494e --- /dev/null +++ b/basic_content/concurrency/main.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include "sort.cpp" + +double sqrt_root(double x){ + if(x < 0){ + throw std::out_of_range("x < 0"); + } + return sqrt(x); +} + +int main(){ +// double y = sqrt_root(-1); + std::future f = std::async(sqrt_root, -1); +// double y = f.get(); + + std::promise p; + std::future f2(p.get_future()); // std::future + assert(f2.valid()); + std::shared_future sf(std::move(f2)); + assert(!f2.valid()); + assert(sf.valid()); + + /*** sort test ***/ + std::default_random_engine e; + std::list l, l2, l3; + for(int i = 0; i < 8e4; ++i){ + l.emplace_back(e() % 10000); + } + l2 = l3 = l; + clock_t start = clock(); + std::thread t(seq_q_sort, std::move(l)); + t.join(); +// auto ans = seq_q_sort(std::move(l)); + std::cout << clock() - start << std::endl; + + start = clock(); + auto ans2 = parallel_q_sort(std::move(l2)); + std::cout << clock() - start << std::endl; + + start = clock(); + l3.sort([](const auto& num1, const auto& num2){ + return num1 < num2; + }); + std::cout << clock() - start << std::endl; + + return 0; +} \ No newline at end of file diff --git a/basic_content/concurrency/sort.cpp b/basic_content/concurrency/sort.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9800609fa62229e14a73bfba8055ae1a6c961807 --- /dev/null +++ b/basic_content/concurrency/sort.cpp @@ -0,0 +1,66 @@ +// +// Created by gmes on 2022/5/30. +// + +#include + +template +std::list seq_q_sort(std::list input){ + if(input.empty()){ + return input; + } + std::list ans; + ans.splice(ans.begin(), input, input.begin()); + const T& pivot = *ans.begin(); + + auto divide_point = std::partition(input.begin(), input.end(), [&](const T& t){ + return t < pivot; + }); + + std::list lower_part; + lower_part.splice(lower_part.end(), input, input.begin(), divide_point); + + auto new_lower(seq_q_sort(std::move(lower_part))); + auto new_higher(seq_q_sort(std::move(input))); + + ans.splice(ans.end(), new_higher); + ans.splice(ans.begin(), new_lower); + return ans; +} + +template +std::list parallel_q_sort(std::list input){ + if(input.empty()){ + return input; + } + std::list ans; + ans.splice(ans.begin(), input, input.begin()); + const T& pivot = *ans.begin(); + + auto divide_point = std::partition(input.begin(), input.end(), [&](const T& t){ + return t < pivot; + }); + + std::list lower_part; + lower_part.splice(lower_part.end(), input, input.begin(), divide_point); + +// auto new_lower(seq_q_sort(std::move(lower_part))); + std::future> new_lower( // list前半部分操作由另一线程执行 + std::async(¶llel_q_sort, std::move(lower_part))); + auto new_higher(seq_q_sort(std::move(input))); + + ans.splice(ans.end(), new_higher); + ans.splice(ans.begin(), new_lower.get()); + return ans; +} + +// spawn_task() +template +std::future::type> spawn_task(F&& f, A&& a){ + typedef typename std::result_of::type ans_type; + std::packaged_task task(std::forward(f)); + std::future ans(task.get_future()); + std::thread t(std::move(task), std::forward(a)); + t.detach(); + return ans; +} \ No newline at end of file