Skip to content

Commit 55fdd28

Browse files
authored
Merge pull request #49 from urbytes21/dev_branch_3
id 1773390893
2 parents db35477 + f1464a6 commit 55fdd28

15 files changed

Lines changed: 816 additions & 9 deletions

src/core/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ set(CORE_SOURCES
8787

8888
# Date and time
8989
${CMAKE_CURRENT_SOURCE_DIR}/datetime/CTime.cpp
90+
91+
# Concurrency
92+
${CMAKE_CURRENT_SOURCE_DIR}/concurrency/ThreadManagement.cpp
93+
${CMAKE_CURRENT_SOURCE_DIR}/concurrency/SharingData.cpp
94+
${CMAKE_CURRENT_SOURCE_DIR}/concurrency/RaceCondition.cpp
95+
${CMAKE_CURRENT_SOURCE_DIR}/concurrency/ConditionVariable.cpp
96+
${CMAKE_CURRENT_SOURCE_DIR}/concurrency/FuturePromise.cpp
9097
)
9198

9299
# Export CORE_SOURCES to the parent CMakeLists.txt
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include <iostream>
2+
#include <string>
3+
4+
#include <condition_variable>
5+
#include <mutex>
6+
#include <thread>
7+
8+
#include "ExampleRegistry.h"
9+
10+
namespace {
11+
12+
std::mutex mutex;
13+
std::condition_variable cv;
14+
std::string data;
15+
bool ready = false;
16+
bool finish = false;
17+
18+
void worker_thread() {
19+
std::unique_lock g_mutex(mutex);
20+
21+
std::cout << "worker_thread started. Waiting for data \n";
22+
cv.wait(g_mutex, []() { return ready; });
23+
std::cout << "worker_thread proccessing data \n";
24+
data += " after processing";
25+
finish = true;
26+
cv.notify_one();
27+
}
28+
29+
void run() {
30+
std::thread w_thread(worker_thread);
31+
32+
// send data
33+
std::cout << "main_thread signals data ready for processing\n";
34+
{
35+
std::unique_lock g_mutex(mutex);
36+
data = "dummy data";
37+
ready = true;
38+
}
39+
cv.notify_one();
40+
41+
// wait for worker
42+
{
43+
std::unique_lock g_mutex(mutex);
44+
cv.wait(g_mutex, []() { return finish; });
45+
}
46+
std::cout << "main_thread data: " << data << '\n';
47+
w_thread.join();
48+
}
49+
} // namespace
50+
51+
class ConditionVariable : public IExample {
52+
53+
std::string group() const override { return "core/concurrency"; }
54+
std::string name() const override { return "ConditionVariable"; }
55+
std::string description() const override {
56+
return "The examples for <thread> condition variable";
57+
}
58+
59+
void execute() override { run(); }
60+
};
61+
62+
REGISTER_EXAMPLE(ConditionVariable, "core/concurrency", "ConditionVariable");
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#include <chrono>
2+
#include <future>
3+
#include <iostream>
4+
#include <string>
5+
#include <thread>
6+
7+
#include "ExampleRegistry.h"
8+
9+
namespace Async {
10+
int async_worker() {
11+
std::cout << "[worker] started, needs 2000 ms\n";
12+
std::this_thread::sleep_for(std::chrono::seconds(2));
13+
std::cout << "[worker] finished\n";
14+
return 1000;
15+
}
16+
17+
void run() {
18+
std::cout << "\n=== std::promise/std::future example ===\n";
19+
auto start = std::chrono::steady_clock::now();
20+
21+
// launch heavy_work asynchronously and get a future
22+
std::future<int> futur =
23+
std::async(std::launch::async, []() { return async_worker(); });
24+
25+
std::cout << "[main] async launched\n";
26+
for (int i = 1; i <= 4; ++i) {
27+
std::this_thread::sleep_for(std::chrono::milliseconds(400));
28+
auto now = std::chrono::steady_clock::now();
29+
auto elapsed =
30+
std::chrono::duration_cast<std::chrono::milliseconds>(now - start)
31+
.count();
32+
33+
std::cout << "[main] doing other work... " << elapsed << " ms\n";
34+
}
35+
36+
// get result
37+
int result = futur.get();
38+
39+
auto end = std::chrono::steady_clock::now();
40+
auto total =
41+
std::chrono::duration_cast<std::chrono::milliseconds>(end - start)
42+
.count();
43+
44+
std::cout << "[main] result = " << result << '\n';
45+
std::cout << "[main] total time = " << total << " ms\n";
46+
}
47+
48+
} // namespace Async
49+
50+
namespace Simple {
51+
void promise_worker(std::promise<int>* prom) {
52+
std::cout << "[worker] started, needs 2000 ms\n";
53+
std::this_thread::sleep_for(std::chrono::seconds(2));
54+
std::cout << "[worker] finished\n";
55+
prom->set_value(100);
56+
}
57+
58+
void run() {
59+
std::cout << "\n=== std::async example ===\n";
60+
auto start = std::chrono::steady_clock::now();
61+
62+
// create a promise and future
63+
std::promise<int> promis;
64+
std::future<int> futur = promis.get_future();
65+
66+
// start heavy work async
67+
std::thread thread(promise_worker, &promis);
68+
69+
std::cout << "[main] async launched\n";
70+
for (int i = 1; i <= 4; ++i) {
71+
std::this_thread::sleep_for(std::chrono::milliseconds(400));
72+
auto now = std::chrono::steady_clock::now();
73+
auto elapsed =
74+
std::chrono::duration_cast<std::chrono::milliseconds>(now - start)
75+
.count();
76+
77+
std::cout << "[main] doing other work... " << elapsed << " ms\n";
78+
}
79+
80+
// get result
81+
int result = futur.get();
82+
83+
auto end = std::chrono::steady_clock::now();
84+
auto total =
85+
std::chrono::duration_cast<std::chrono::milliseconds>(end - start)
86+
.count();
87+
88+
std::cout << "[main] result = " << result << '\n';
89+
std::cout << "[main] total time = " << total << " ms\n";
90+
91+
thread.join();
92+
}
93+
94+
} // namespace Simple
95+
96+
class FuturePromise : public IExample {
97+
98+
std::string group() const override { return "core/concurrency"; }
99+
std::string name() const override { return "FuturePromise"; }
100+
std::string description() const override {
101+
return "The examples for <future>";
102+
}
103+
104+
void execute() override {
105+
Async::run();
106+
107+
Simple::run();
108+
}
109+
};
110+
111+
REGISTER_EXAMPLE(FuturePromise, "core/concurrency", "FuturePromise");

0 commit comments

Comments
 (0)