Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,13 @@ set(CORE_SOURCES

# Date and time
${CMAKE_CURRENT_SOURCE_DIR}/datetime/CTime.cpp

# Concurrency
${CMAKE_CURRENT_SOURCE_DIR}/concurrency/ThreadManagement.cpp
${CMAKE_CURRENT_SOURCE_DIR}/concurrency/SharingData.cpp
${CMAKE_CURRENT_SOURCE_DIR}/concurrency/RaceCondition.cpp
${CMAKE_CURRENT_SOURCE_DIR}/concurrency/ConditionVariable.cpp
${CMAKE_CURRENT_SOURCE_DIR}/concurrency/FuturePromise.cpp
)

# Export CORE_SOURCES to the parent CMakeLists.txt
Expand Down
62 changes: 62 additions & 0 deletions src/core/concurrency/ConditionVariable.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include <iostream>
#include <string>

#include <condition_variable>
#include <mutex>
#include <thread>

#include "ExampleRegistry.h"

namespace {

std::mutex mutex;
std::condition_variable cv;
std::string data;
bool ready = false;
bool finish = false;

void worker_thread() {
std::unique_lock g_mutex(mutex);

std::cout << "worker_thread started. Waiting for data \n";
cv.wait(g_mutex, []() { return ready; });
std::cout << "worker_thread proccessing data \n";
data += " after processing";
finish = true;
cv.notify_one();
}

void run() {
std::thread w_thread(worker_thread);

// send data
std::cout << "main_thread signals data ready for processing\n";
{
std::unique_lock g_mutex(mutex);
data = "dummy data";
ready = true;
}
cv.notify_one();

// wait for worker
{
std::unique_lock g_mutex(mutex);
cv.wait(g_mutex, []() { return finish; });
}
std::cout << "main_thread data: " << data << '\n';
w_thread.join();
}
} // namespace

class ConditionVariable : public IExample {

std::string group() const override { return "core/concurrency"; }
std::string name() const override { return "ConditionVariable"; }
std::string description() const override {
return "The examples for <thread> condition variable";
}

void execute() override { run(); }
};

REGISTER_EXAMPLE(ConditionVariable, "core/concurrency", "ConditionVariable");
111 changes: 111 additions & 0 deletions src/core/concurrency/FuturePromise.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#include <chrono>
#include <future>
#include <iostream>
#include <string>
#include <thread>

#include "ExampleRegistry.h"

namespace Async {
int async_worker() {
std::cout << "[worker] started, needs 2000 ms\n";
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "[worker] finished\n";
return 1000;
}

void run() {
std::cout << "\n=== std::promise/std::future example ===\n";
auto start = std::chrono::steady_clock::now();

// launch heavy_work asynchronously and get a future
std::future<int> futur =
std::async(std::launch::async, []() { return async_worker(); });

std::cout << "[main] async launched\n";
for (int i = 1; i <= 4; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(400));
auto now = std::chrono::steady_clock::now();
auto elapsed =
std::chrono::duration_cast<std::chrono::milliseconds>(now - start)
.count();

std::cout << "[main] doing other work... " << elapsed << " ms\n";
}

// get result
int result = futur.get();

auto end = std::chrono::steady_clock::now();
auto total =
std::chrono::duration_cast<std::chrono::milliseconds>(end - start)
.count();

std::cout << "[main] result = " << result << '\n';
std::cout << "[main] total time = " << total << " ms\n";
}

} // namespace Async

namespace Simple {
void promise_worker(std::promise<int>* prom) {
std::cout << "[worker] started, needs 2000 ms\n";
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "[worker] finished\n";
prom->set_value(100);
}

void run() {
std::cout << "\n=== std::async example ===\n";
auto start = std::chrono::steady_clock::now();

// create a promise and future
std::promise<int> promis;
std::future<int> futur = promis.get_future();

// start heavy work async
std::thread thread(promise_worker, &promis);

std::cout << "[main] async launched\n";
for (int i = 1; i <= 4; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(400));
auto now = std::chrono::steady_clock::now();
auto elapsed =
std::chrono::duration_cast<std::chrono::milliseconds>(now - start)
.count();

std::cout << "[main] doing other work... " << elapsed << " ms\n";
}

// get result
int result = futur.get();

auto end = std::chrono::steady_clock::now();
auto total =
std::chrono::duration_cast<std::chrono::milliseconds>(end - start)
.count();

std::cout << "[main] result = " << result << '\n';
std::cout << "[main] total time = " << total << " ms\n";

thread.join();
}

} // namespace Simple

class FuturePromise : public IExample {

std::string group() const override { return "core/concurrency"; }
std::string name() const override { return "FuturePromise"; }
std::string description() const override {
return "The examples for <future>";
}

void execute() override {
Async::run();

Simple::run();
}
};

REGISTER_EXAMPLE(FuturePromise, "core/concurrency", "FuturePromise");
Loading
Loading