4

Based on C++ Equivalent to Java's BlockingQueue

void push(T const& value) { // original version
        {
            std::unique_lock<std::mutex> lock(this->d_mutex);
            d_queue.push_front(value);
        }
        this->d_condition.notify_one();
    }

void push(T const& value) { // my question
        //{ // comment out the scope
            std::unique_lock<std::mutex> lock(this->d_mutex);
            d_queue.push_front(value);
        //} // comment out the scope
        this->d_condition.notify_one();
    }

Question: why we should introduce a local scope {} to cover the std::unique_lock inside the put function? Is it because we should release the lock first before calling notify_one otherwise the lock is hold while we calling the notify_one?

T pop() {
        std::unique_lock<std::mutex> lock(this->d_mutex);
        this->d_condition.wait(lock, [=]{ return !this->d_queue.empty(); });
        T rc(std::move(this->d_queue.back()));
        this->d_queue.pop_back();
        return rc;
    }

Question: why we should use [=] inside the pop function?

Community
  • 1
  • 1
q0987
  • 34,938
  • 69
  • 242
  • 387

1 Answers1

8

Is it because we should release the lock first before calling notify_one() otherwise the lock is hold while we calling the notify_one()?

Correct. It's possible that the other thread spins up and attempts to grab the queue's lock before the producer thread has released it. Which would cause it to wake up (because of the condition variable), and then go back to sleep (because of the lock).

why we should use [=] inside the pop function?

We are accessing this. The lambda needs to access d_queue through some method, and they chose copying this by value.

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
  • Q2> why not copying `this` by reference? – q0987 Jun 26 '14 at 19:20
  • 2
    @q0987: It's a pointer, either would be fine. I'd probably do it as a reference personally. – Bill Lynch Jun 26 '14 at 19:20
  • Or `[=this]` be precise. – q0987 Jun 26 '14 at 19:22
  • 2
    @q0987 That would be a syntax error. If you want to explicitly capture only `this`, and not implicitly capture it via a capture default (`[=]` or `[&]`), then use `[this]`. – Praetorian Jun 26 '14 at 19:28
  • @Praetorian, you are absolutely right. I just found out that `this` is a special variable. `[this]` means to capture the this pointer of the enclosing class. – q0987 Jun 26 '14 at 19:31
  • @q0987 `this` is a prvalue, capturing it by reference makes as much sense as capturing `false` or `243` by reference. You can only capture `this` by copy. – Casey Jun 26 '14 at 20:11