Reputation: 2625
How to do it in C++?
Upvotes: 1
Views: 2630
Reputation: 8074
Here's a simple example to get you started:
std::mutex
.std::shared_mutex
.std::shared_lock
on the std::shared_mutex
, allowing simultaneous reads; while each writer thread uses a std::unique_lock
on the std::shared_lock
, granting them exclusive access to the buffer.#include <chrono>
#include <fmt/core.h>
#include <iostream> // cout
#include <random> // default_random_engine, random_device, uniform_int_distribution
#include <thread> // this_thread
#include <vector>
#include <mutex> // unique_lock
#include <shared_mutex> // shared_lock, shared_mutex
constinit const size_t buffer_size{5};
constinit int buffer[buffer_size]{};
constinit std::shared_mutex buffer_mtx{};
auto random_sleep_for = [](int low, int high) {
std::default_random_engine eng{std::random_device{}()};
std::uniform_int_distribution<> dist{low, high};
std::this_thread::sleep_for(std::chrono::milliseconds{dist(eng)});
};
auto reader = [](int i){
for (size_t n{0}; n < buffer_size; ++n) {
random_sleep_for(50, 100);
std::shared_lock lck{buffer_mtx}; // shared access with other readers
std::cout << fmt::format("Thread {} reading {} from buffer[{}]\n",
i, buffer[n], n);
random_sleep_for(50, 100);
std::cout << fmt::format("Thread {} done reading {} from buffer[{}]\n",
i, buffer[n], n);
}
};
auto writer = [](int i){
for (size_t n{0}; n < buffer_size; ++n) {
random_sleep_for(40, 80);
std::unique_lock lck{buffer_mtx}; // exclusive access to buffer
std::cout << fmt::format("\tThread {} writing {} to buffer[{}]\n",
i, i*(n+1), n);
buffer[n] = i*(n+1);
std::cout << fmt::format("\tThread {} done writing {} to buffer[{}]\n",
i, i*(n+1), n);
}
};
int main()
{
std::vector<std::thread> writers{};
std::vector<std::thread> readers{};
for (int i{0}; i < 5; ++i) {
writers.emplace_back(writer, i + 1);
readers.emplace_back(reader, i + 1);
}
for (int i{0}; i < 5; ++i) {
writers[i].join();
readers[i].join();
}
}
// Outputs:
//
// Thread 5 writing 5 to buffer[0]
// Thread 5 done writing 5 to buffer[0]
// Thread 1 writing 1 to buffer[0]
// Thread 1 done writing 1 to buffer[0]
// Thread 5 reading 1 from buffer[0]
// Thread 4 reading 1 from buffer[0]
// Thread 3 reading 1 from buffer[0]
// Thread 2 reading 1 from buffer[0]
// Thread 1 reading 1 from buffer[0]
// Thread 5 done reading 1 from buffer[0]
// Thread 3 done reading 1 from buffer[0]
// Thread 2 done reading 1 from buffer[0]
// Thread 4 done reading 1 from buffer[0]
// Thread 1 done reading 1 from buffer[0]
// ...
Upvotes: 2