Created
April 21, 2022 00:47
-
-
Save sgtcortez/3bd46c378391383ce91be82e2dd5db71 to your computer and use it in GitHub Desktop.
This is a very simple implementation of a semaphore using c++, just for learning purposes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Semaphore.hpp" | |
#include <chrono> | |
#include <condition_variable> | |
#include <cstdint> | |
#include <iostream> | |
#include <string> | |
#include <thread> | |
using namespace std; | |
using namespace ramboindustries; | |
void acquire(Semaphore& semaphore) | |
{ | |
this_thread::sleep_for(std::chrono::seconds(3)); | |
semaphore.acquire(); | |
cout << this_thread::get_id() << " says: I Got it !!!" << endl; | |
this_thread::sleep_for(std::chrono::seconds(10)); | |
cout << this_thread::get_id() << " says: I am going to release it now!" << endl; | |
semaphore.release(); | |
} | |
int main(int argc, char** argv) | |
{ | |
if (argc != 3) | |
{ | |
cerr << "Usage: " << argv[0] << " <threads-number> <permits-number> " << endl; | |
return 1; | |
} | |
const std::uint16_t threads_number = std::atoi(argv[1]); | |
const std::uint16_t permits_number = std::atoi(argv[2]); | |
Semaphore semaphore(permits_number); | |
thread threads[threads_number]; | |
for (auto index = 0; index < sizeof(threads) / sizeof(threads[0]); index++) | |
{ | |
threads[index] = thread(acquire, ref(semaphore)); | |
} | |
for (auto& thread: threads) | |
{ | |
thread.join(); | |
} | |
cout << "Done ..." << endl; | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CPP_C=clang++ | |
C_FLAGS=-std=c++14 -g | |
BINARY=Main.out | |
LINK=-lpthread | |
OBJECTS=\ | |
Semaphore.o | |
all: $(BINARY) | |
Semaphore.o: Semaphore.cpp Semaphore.hpp | |
@$(CPP_C) -c $(C_FLAGS) Semaphore.cpp | |
$(BINARY): Main.cpp $(OBJECTS) | |
@$(CPP_C) $(C_FLAGS) -o $@ Main.cpp $(LINK) $(OBJECTS) | |
clear: | |
@rm -Rf *.o *.out 1>/dev/null 2>&1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Semaphore.hpp" | |
#include "Semaphore.hpp" | |
#include <cstdint> | |
#include <mutex> | |
#include <iostream> | |
#include <thread> | |
#include <string> | |
using namespace std; | |
ramboindustries::Semaphore::Semaphore(const std::uint16_t permits) noexcept | |
: initial_permits(permits) | |
{ | |
cout << "Initialized semaphore with: " << to_string(permits) << " permits ..." << endl; | |
this->permits = permits; | |
} | |
void ramboindustries::Semaphore::acquire() noexcept | |
{ | |
cout << "Thread: " << this_thread::get_id() << " is trying to acquire a permit" << endl; | |
auto lock = unique_lock<std::mutex>(mutex); | |
if (permits == 0) | |
{ | |
cout << "No permits avaialable ... " << " Thread: " << this_thread::get_id() << " is going to wait ..." << endl; | |
condition.wait(lock); | |
} | |
cout << "Thread: " << this_thread::get_id() << " got a permit ..." << endl; | |
permits--; | |
} | |
void ramboindustries::Semaphore::release() noexcept | |
{ | |
cout << "Thread: " << this_thread::get_id() << " is releasing the permit ..." << endl; | |
auto lock = std::unique_lock<std::mutex>(mutex); | |
permits++; | |
condition.notify_one(); | |
} | |
std::uint16_t ramboindustries::Semaphore::get_initial_permits() const noexcept | |
{ | |
return initial_permits; | |
} | |
std::uint16_t ramboindustries::Semaphore::get_permits() const noexcept | |
{ | |
return permits; | |
} | |
ramboindustries::BinarySemaphore::BinarySemaphore() noexcept | |
: Semaphore(1) | |
{ | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <cstdint> | |
#include <condition_variable> | |
#include <mutex> | |
namespace ramboindustries { | |
class Semaphore | |
{ | |
private: | |
const std::uint16_t initial_permits; | |
std::uint16_t permits; | |
std::mutex mutex; | |
std::condition_variable condition; | |
public: | |
Semaphore(const std::uint16_t permits) noexcept; | |
void acquire() noexcept; | |
void release() noexcept; | |
std::uint16_t get_initial_permits() const noexcept; | |
std::uint16_t get_permits() const noexcept; | |
}; | |
class BinarySemaphore : public Semaphore | |
{ | |
public: | |
BinarySemaphore() noexcept; | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment