-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathPackagedTask_02.cpp
More file actions
130 lines (91 loc) · 3.3 KB
/
PackagedTask_02.cpp
File metadata and controls
130 lines (91 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// ===========================================================================
// PackagedTask_02.cpp // Packaged Task
// ===========================================================================
#include "../Logger/Logger.h"
#include <cstddef>
#include <deque>
#include <future>
#include <iostream>
#include <thread>
#include <utility>
namespace PackagedTask {
static int calcSum(int a, int b) {
Logger::log(std::cout, "calcSum: ", a, " + ", b);
return a + b;
}
static int calcSumRange(int a, int b) {
Logger::log(std::cout, "calcSumRange: ", a, " => ", b);
int sum{};
for (int i{ a }; i != b; ++i) {
sum += i;
}
Logger::log(std::cout, "sum: ", sum);
return sum;
}
static void test_01() {
// define a task
std::packaged_task<int(int, int)> task{ calcSum };
// get the future object for this task
std::future<int> future{ task.get_future() };
// invoke the function synchronously
// task(123, 456);
// or
// invoke the function asynchronously
std::thread t{ std::move(task), 123, 456 };
t.detach();
// do some arbitrary work ......
std::this_thread::sleep_for(std::chrono::seconds{ 2 });
// get the result
int sum{ future.get() };
Logger::log(std::cout, "123 + 456 = ", sum);
}
static void test_02() {
Logger::log(std::cout, "Start: ");
constexpr std::size_t MaxTasks{ 4 };
std::deque<std::packaged_task<int(int, int)>> tasks;
std::deque<std::future<int>> futures;
// define tasks, store corresponding futures
for (std::size_t i{}; i != MaxTasks; i++) {
std::packaged_task<int(int, int)> task{ calcSumRange };
std::future<int> future{ task.get_future() };
tasks.push_back(std::move(task));
futures.push_back(std::move(future));
}
int begin{ 1 };
int increment{ 100 };
int end{ begin + increment };
// execute each task in a separate thread
for (std::size_t i = 0; i != MaxTasks; i++) {
std::packaged_task<int(int, int)> task{ std::move(tasks.front()) };
tasks.pop_front();
// invoke the function synchronously
// task(begin, end);
// or
// invoke the function asynchronously
std::thread t{ std::move(task), begin, end };
t.detach();
begin = end;
end += increment;
}
// get the results
int sum{};
for (std::size_t i = 0; i != MaxTasks; i++) {
std::future<int> future{ std::move(futures.front()) };
futures.pop_front();
int partialSum{ future.get() };
sum += partialSum;
}
// use gauss to verify: n * (n+1) / 2 ==> 80200
Logger::log(std::cout, "Sum of 0 ", " .. ", (end - increment - 1), " = ", sum);
Logger::log(std::cout, "Done.");
}
}
void test_packaged_task_02 ()
{
using namespace PackagedTask;
test_01();
test_02();
}
// ===========================================================================
// End-of-File
// ===========================================================================