0
#include <mutex>
#include <queue>
#include <thread>
#include <vector>
#include <iostream>

template <typename T>
class ThreadSafeQueue {
 private:
  std::queue<T> data_;
  mutable std::mutex mut_;
  std::condition_variable cv_;

 public:
  ThreadSafeQueue() {}
  ThreadSafeQueue(const ThreadSafeQueue& other) {
    std::lock_guard<std::mutex> lk(other.mut_);
    data_ = other.data_;
  }

  void push(T item) {
    std::lock_guard<std::mutex> lk(mut_);
    data_.push(std::move(item));
    cv_.notify_one();
  }

  void wait_and_pop(T& item) {
    std::unique_lock<std::mutex> ulk(mut_);
    std::cout << "Here " << std::endl;
    cv_.wait(ulk, [this] {
       return !data_.empty(); });
    item = std::move(data_.front());
    data_.pop();
  }

  bool try_pop(T& item) {
    std::lock_guard<std::mutex> lk(mut_);
    if (data_.empty()) return false;
    item = data_.front();
    data_.pop();
    return true;
  }

  bool empty() const {
    std::lock_guard<std::mutex> lk(mut_);
    return data_.empty();
  }
};

int main() {
  std::vector<int> output(3);
  std::vector<std::thread> threads;
  for (int i = 0; i < 3; i++) {
    threads.push_back(std::thread(&util::ThreadSafeQueue<int>::wait_and_pop,
                                  &ts_que, std::ref(output[i])));
    threads[i].join(); // Code is hanging here after the first thread joined.
  }
}

Trying the threadsafe queue example from currency textbook, but it seems the wait_and_pop condition_variable wait is hanging and blocking.

Was expecting the wait to be non-blocking? In the code, after first thread join, it is handing there and wait for the signal inside the wait_and_pop where the condition_variable is waiting for some data.

7
  • 3
    How is it possible for a wait to be non-blocking? If it doesn't block, it doesn't wait for anything. Commented Dec 25, 2023 at 22:55
  • 3
    The whole point of cv_.wait(ulk, [this] { return !data_.empty(); }); is to block and wait until the condition !data_.empty(); becomes true. That's why it's called "condition variable". Commented Dec 25, 2023 at 23:07
  • 3
    The purpose of join is to wait for a thread to finish. Commented Dec 26, 2023 at 2:39
  • cv_.wait will block the thread it is running, what I have observed is the whole program is hanging? is this expected? thanks Commented Dec 26, 2023 at 3:55
  • The program blocks itself, so it behaves exactly as intended. Commented Dec 26, 2023 at 9:57

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.