Skip to content

played with thread syncing - #10

Open
kunzhutich wants to merge 2 commits into
mainfrom
threading_sync
Open

played with thread syncing#10
kunzhutich wants to merge 2 commits into
mainfrom
threading_sync

Conversation

@kunzhutich

Copy link
Copy Markdown
Owner

No description provided.

@maksimpustovoyt maksimpustovoyt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address 1 comment and merge

Comment thread henryPractice/thread_sync/main.cpp Outdated
Q(size_t cap) : _cap(cap) {}

void add(T x) {
unique_lock<mutex> lock(m);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

identity

@maksimpustovoyt maksimpustovoyt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address 1 comment and merge
Let's discuss today the strategy

Comment thread henryPractice/thread_sync/main.cpp Outdated
public:
Q(size_t cap) : _cap(cap) {}

void add(T x) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss T x, Can it be const T & ? or can it be std::move()

@kunzhutich

Copy link
Copy Markdown
Owner Author

Maksim, I think this implementation is wrong:

while (true) {
    not_full.wait(lock);              // waits even if there's already space
    if (queue.size() < _cap) break;   // only checked *after* waking
}

If add() is called when the queue already has space (queue.size() < _cap), no other thread is required to call not_full.notify_one(). Since condition variables do not queue notifications, this thread can go to sleep with space available and never wake up → potential infinite wait.

Also, according to cppreference.com, any thread that intends to wait on a std::condition_variable must:

  1. Check the condition, in case it was already updated and notified.
  2. Call wait, wait_for, or wait_until on the std::condition_variable (atomically releases the mutex and suspends thread execution until the condition variable is notified, a timeout expires, or a spurious wakeup occurs, then atomically acquires the mutex before returning).
  3. Check the condition and resume waiting if not satisfied.

// }
// }

while (queue.size() >= _cap) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already discuss it... the code has race for queue.size()

// }
// }

while (queue.empty()) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already discuss it... the code has race for queue.empty()

Comment on lines +78 to +81
while (queue.size() >= _cap) {
if (not_full.wait_for(lk, timeout) == cv_status::timeout)
return false;
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already discuss it... the code has race for queue.size()

Comment on lines +91 to +94
while (queue.empty()) {
if (not_empty.wait_for(lk, timeout) == cv_status::timeout)
return false;
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already discuss it... the code has race for queue.empty()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants