Skip to content

Instantly share code, notes, and snippets.

@farhangamary
Last active March 1, 2024 01:36
Show Gist options
  • Select an option

  • Save farhangamary/ae9803f917059a3e5cb26a58277d8d53 to your computer and use it in GitHub Desktop.

Select an option

Save farhangamary/ae9803f917059a3e5cb26a58277d8d53 to your computer and use it in GitHub Desktop.
A shared resource which can get read and written alternately among multiple threads
cmake_minimum_required(VERSION 3.18)
project(multith
VERSION 0.1
DESCRIPTION "A sample of a shared resource")
set(CMAKE_CXX_STANDARD 17)
add_executable(multith starter.cpp)
#include "Message.hpp"
Message::Message() : value_(""), last_writer_id_(-1), last_reader_id_(-1) {}
Message::~Message() {}
void Message::set_value(std::string value, int writer_id)
{
std::unique_lock write_lock(mtx_);
cv_.wait(write_lock,
[writer_id, this]
{ return can_write(writer_id); });
value_ = value;
last_writer_id_ = writer_id;
cv_.notify_all();
}
std::string Message::get_value(int reader_id)
{
std::unique_lock read_lock(mtx_);
cv_.wait(read_lock,
[reader_id, this]
{ return can_read(reader_id); });
last_reader_id_ = reader_id;
cv_.notify_all();
return value_;
}
bool Message::can_write(int writer_id)
{
return writer_id == last_reader_id_ || value_.empty();
}
bool Message::can_read(int reader_id)
{
return reader_id != last_writer_id_ && !value_.empty();
}
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
class Message
{
private:
std::string value_;
int last_writer_id_;
int last_reader_id_;
std::condition_variable cv_;
std::mutex mtx_;
public:
Message();
virtual ~Message();
void set_value(std::string value, int writer_id);
std::string get_value(int reader_id);
bool can_read(int reader_id);
bool can_write(int writer_id);
};
$ cmake -S . -B bin
-- The C compiler identification is GNU 11.4.0
-- The CXX compiler identification is GNU 11.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /***/bin
$ cmake --build bin
[ 50%] Building CXX object CMakeFiles/multith.dir/starter.cpp.o
[100%] Linking CXX executable multith
[100%] Built target multith
$ bin/multith
Hello and welcome.
Th#1 writes: "InitVAL"
Th#2 read__: "InitVAL"
Th#2 writes: "InitVAL0"
Th#1 read__: "InitVAL0"
Th#1 writes: "InitVAL00"
Th#2 read__: "InitVAL00"
Th#2 writes: "InitVAL001"
Th#1 read__: "InitVAL001"
Th#1 writes: "InitVAL0011"
Th#2 read__: "InitVAL0011"
Th#2 writes: "InitVAL00112"
Th#1 read__: "InitVAL00112"
Th#1 writes: "InitVAL001122"
Th#2 read__: "InitVAL001122"
Th#2 writes: "InitVAL0011223"
Th#1 read__: "InitVAL0011223"
Th#1 writes: "InitVAL00112233"
Th#2 read__: "InitVAL00112233"
Th#2 writes: "InitVAL001122334"
Th#1 read__: "InitVAL001122334"
Th#1 writes: "InitVAL0011223344"
#include <iostream>
#include <thread>
#include "Message.cpp"
using namespace std;
shared_ptr<Message> msg;
void chat(int id)
{
if (id == 1)
{
msg.get()->set_value("InitVAL", id);
cout << "Th#" << id << " writes: \"InitVAL\"" << endl;
this_thread::sleep_for(chrono::milliseconds(75));
}
for (int i = 0; i < 5; ++i)
{
string current_msg = msg.get()->get_value(id);
cout << "Th#" << id << " read__: \"" << current_msg << "\"" << endl;
this_thread::sleep_for(chrono::milliseconds(75));
string new_message = current_msg + to_string(i);
cout << "Th#" << id << " writes: \"" << new_message << "\"" << endl;
msg.get()->set_value(new_message, id);
this_thread::sleep_for(chrono::milliseconds(75));
}
}
int main(int args_count, char *args[])
{
msg = make_shared<Message>();
cout << "Hello and welcome." << endl
<< endl;
thread th_2(chat, 2);
thread th_1(chat, 1);
th_1.join();
th_2.join();
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment