From 39e08c0cfc879c67f2dafac54d73ce6db3ceeb41 Mon Sep 17 00:00:00 2001 From: Bo Wang Date: Tue, 1 Nov 2016 00:16:55 -0400 Subject: [PATCH] chapter 4 code --- ch4/Makefile | 22 ++++++++++ ch4/queue.cpp | 104 ++++++++++++++++++++++++++++++++++++++++++++++ ch4/quicksort.cpp | 74 +++++++++++++++++++++++++++++++++ 3 files changed, 200 insertions(+) create mode 100644 ch4/Makefile create mode 100644 ch4/queue.cpp create mode 100644 ch4/quicksort.cpp diff --git a/ch4/Makefile b/ch4/Makefile new file mode 100644 index 0000000..74eef48 --- /dev/null +++ b/ch4/Makefile @@ -0,0 +1,22 @@ +CPP = g++ +CPPFLAGS = -g -std=c++0x +OFLAG = -o +.SUFFIXES : .o .cpp .c +.cpp.o : + $(CPP) $(CPPFLAGS) -c $< +.c.o : + $(CPP) $(CPPFLAGS) -c $< + +PROGS = queue quicksort + +all: $(PROGS) + +queue: queue.o + $(CPP) $(OFLAG) queue queue.o -lpthread + +quicksort: quicksort.o + $(CPP) $(OFLAG) quicksort quicksort.o -lpthread + +clean: + rm -f ${PROGS} *.o + diff --git a/ch4/queue.cpp b/ch4/queue.cpp new file mode 100644 index 0000000..d8a7e46 --- /dev/null +++ b/ch4/queue.cpp @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include +#include +#include + +template +class queue +{ + private: + mutable std::mutex mut; + std::queue data_queue; + std::condition_variable data_cond; + + public: + queue(){} + + queue(const queue& other) + { + std::lock_guard lk(other.mut); + data_queue = other.data_queue; + } + + void push(T new_value) + { + std::lock_guard lk(mut); + data_queue.push(new_value); + data_cond.notify_one(); + } + + void wait_and_pop(T& value) + { + std::unique_lock lk(mut); + data_cond.wait(lk, [this]{return !data_queue.empty();}); + value = data_queue.front(); + data_queue.pop(); + } + + std::shared_ptr wait_and_pop() + { + std::unique_lock lk(mut); + data_cond.wait(lk, [this]{return !data_queue.empty();}); + std::shared_ptr res(std::make_shared(data_queue.front())); + data_queue.pop(); + return res; + } + + bool try_pop(T& value) + { + std::lock_guard lk(mut); + if (data_queue.empty()) { + return false; + } + value = data_queue.front(); + data_queue.pop(); + return true; + } + + std::shared_ptr try_pop() + { + std::lock_guard lk(mut); + if (data_queue.empty()) { + return std::shared_ptr(); + } + std::shared_ptr res(std::make_shared(data_queue.front())); + data_queue.pop(); + return res; + } + + bool empty() const + { + std::lock_guard lk(mut); + return data_queue.empty(); + } +}; + +void push(queue* q) +{ + for (int i = 0; i < 10; ++i) { + //std::cout << "pushing " << i << std::endl; + printf("pushing %d\n", i); + q->push(i); + } +} + +void pop(queue* q) +{ + for (int i = 0; i < 10; ++i) { + printf("poping %d\n", *q->wait_and_pop()); + } +} + +int main() +{ + queue q; + std::thread t1(push,&q); + std::thread t2(pop,&q); + t1.join(); + t2.join(); + return 0; +} + diff --git a/ch4/quicksort.cpp b/ch4/quicksort.cpp new file mode 100644 index 0000000..1eab835 --- /dev/null +++ b/ch4/quicksort.cpp @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include +#include +#include + +std::ostream& operator<<(std::ostream& ostr, const std::list& list) +{ + for (auto &i : list) { + ostr << " " << i; + } + return ostr; +} + +template +std::list sequential_quick_sort(std::list input) +{ + if(input.empty()) + { + return input; + } + std::list result; + result.splice(result.begin(),input,input.begin()); + T const& pivot=*result.begin(); + auto divide_point=std::partition(input.begin(),input.end(), + [&](T const& t){return t lower_part; + lower_part.splice(lower_part.end(),input,input.begin(), + divide_point); + auto new_lower( + sequential_quick_sort(std::move(lower_part))); + auto new_higher( + sequential_quick_sort(std::move(input))); + result.splice(result.end(),new_higher); + result.splice(result.begin(),new_lower); + return result; +} + +template +std::list parallel_quick_sort(std::list input) +{ + if(input.empty()) + { + return input; + } + std::list result; + result.splice(result.begin(),input,input.begin()); + T const& pivot=*result.begin(); + auto divide_point=std::partition(input.begin(),input.end(), + [&](T const& t){return t lower_part; + lower_part.splice(lower_part.end(),input,input.begin(), + divide_point); + std::future > new_lower( + std::async(¶llel_quick_sort,std::move(lower_part))); + auto new_higher( + parallel_quick_sort(std::move(input))); + result.splice(result.end(),new_higher); + result.splice(result.begin(),new_lower.get()); + return result; +} + +int main() +{ + std::list list1 = {4, 2, 1, 5, 8, 9, 7}; + std::list sorted1 = sequential_quick_sort(list1); + std::list sorted2 = parallel_quick_sort(list1); + std::cout << "sorted1: " << sorted1 << std::endl; + std::cout << "sorted2: " << sorted2 << std::endl; + return 0; +} +