From 4b7bf34724fb1a8c0a135ae3127548e495c0ad2c Mon Sep 17 00:00:00 2001 From: Gems <12239620+gems-xu@user.noreply.gitee.com> Date: Wed, 10 May 2023 00:31:48 +0000 Subject: [PATCH] Add concurrency program Signed-off-by: Gems <12239620+gems-xu@user.noreply.gitee.com> --- basic_content/concurrency/README.md | 9 ++++ basic_content/concurrency/main.cpp | 51 ++++++++++++++++++++++ basic_content/concurrency/sort.cpp | 66 +++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 basic_content/concurrency/README.md create mode 100644 basic_content/concurrency/main.cpp create mode 100644 basic_content/concurrency/sort.cpp diff --git a/basic_content/concurrency/README.md b/basic_content/concurrency/README.md new file mode 100644 index 0000000..ac3acc5 --- /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 0000000..2d95b0d --- /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 0000000..9800609 --- /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 -- Gitee