Skip to content

Commit

Permalink
with unique_ptr move version of put and get
Browse files Browse the repository at this point in the history
  • Loading branch information
jurschreuder committed Jan 21, 2024
1 parent 41d64b7 commit 95880b4
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 10 deletions.
36 changes: 29 additions & 7 deletions include/safe_queue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@ class SafeQueue
, c() // condition
{}

~SafeQueue(void)
{}
~SafeQueue(void){}

// Keeps track of the size of the queue
std::atomic<std::uint64_t> size;

// Add an element to the queue.
void put(T t)
{
void put(T t){
std::lock_guard<std::mutex> lock(m);
q.push(t);
size++;
Expand All @@ -36,15 +34,39 @@ class SafeQueue

// Get the "front"-element.
// If the queue is empty, wait till a element is avaiable.
T get(void)
{
T get(void){
std::unique_lock<std::mutex> lock(m);
while(q.empty()){
// release lock as long as the wait and reaquire it afterwards.
c.wait(lock);
}
T val = q.front();
q.pop();
size--;
return val;
}

// Add an element to the queue.
// Takes ownership of the element.
// Use like: queue->put_move(std::move(t))
void put_move(T&& t){
std::lock_guard<std::mutex> lock(m);
q.push(std::move(t));
size++;
c.notify_one();
}

// Get the "front"-element.
// If the queue is empty, wait till a element is avaiable.
// Takes ownership of the object from the queue.
T get_move(void){
std::unique_lock<std::mutex> lock(m);
while(q.empty())
{
// release lock as long as the wait and reaquire it afterwards.
c.wait(lock);
}
T val = q.front();
T val = std::move(q.front());
q.pop();
size--;
return val;
Expand Down
22 changes: 19 additions & 3 deletions src/safe_queue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
int main() {
std::cout << "Simple (thread) Safe Queue example.\n";

std::cout << "=========== Demo 1: Basic ===========\n";
std::cout << "\n=========== Demo 1: Basic ===========\n";

// new queue
SafeQueue<int> basic_queue;
Expand All @@ -26,7 +26,7 @@ int main() {
std::cout << "Item: " << item << "\n";
}

std::cout << "=========== Demo 2: Thread ===========\n";
std::cout << "\n=========== Demo 2: Thread ===========\n";

// new queue
std::shared_ptr<SafeQueue<int>> queue = std::make_shared<SafeQueue<int>>();
Expand All @@ -50,7 +50,7 @@ int main() {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}

std::cout << "=========== Demo 3: Max size ===========\n";
std::cout << "\n=========== Demo 3: Max size ===========\n";

// If the queue is processed too slow and we want to stop
// adding items if there are too many items already
Expand All @@ -63,5 +63,21 @@ int main() {
std::this_thread::sleep_for(std::chrono::milliseconds(500));


std::cout << "\n=== Demo 4: Pass ownership and get ownership from the queue ===\n";

auto big_queue = std::make_shared<SafeQueue<std::unique_ptr<std::vector<int>>>>();

for(int i = 0; i < 100; ++i){
// make some big data
auto big = std::make_unique<std::vector<int>>(1e6);
big_queue->put_move(std::move(big));
}
std::cout << "Added 100 to big_queue\n";

for(int i = 0; i < 100; ++i){
auto big = big_queue->get_move();
}
std::cout << "Got 100 to big_queue\n";

return 0;
}

0 comments on commit 95880b4

Please sign in to comment.