Tôi có cần đồng bộ hóa std::condition_variable/condition_variable_any::notify_one
không?Tôi có cần phải đồng bộ hóa std :: condition_variable/condition_variable_any :: notify_one
Theo tôi có thể thấy, nếu mất thông báo là chấp nhận được - bạn có thể gọi số notify_one
không được bảo vệ (ví dụ như mutex).
Ví dụ, tôi thấy sau thói quen sử dụng (xin lỗi, không nhớ ở đâu):
{
{
lock_guard<mutex> l(m);
// do work
}
c.notify_one();
}
Nhưng, tôi kiểm tra libstdC++ nguồn khác nhau, và tôi thấy:
condition_variable::notify_one
void condition_variable::notify_one() noexcept
{
int __e = __gthread_cond_signal(&_M_cond);
// XXX not in spec
// EINVAL
if (__e)
__throw_system_error(__e);
}
và condition_variable_any::notify_one:
void condition_variable_any::notify_one() noexcept
{
lock_guard<mutex> __lock(_M_mutex);
_M_cond.notify_one();
}
Và đây là cách bố trí của condition_variable_any:
class condition_variable_any
{
condition_variable _M_cond;
mutex _M_mutex;
// data end
Tức là nó chỉ là bao bọc mỏng xung quanh condition_variable + mutex.
Vì vậy, câu hỏi:
- Có thread-an toàn để bảo vệ không
notify_one
bởi mutex cho một trong haicondition_variable_any
hoặccondition_variable
? - Tại sao việc triển khai điều kiện_variable_any sử dụng mutex bổ sung?
- Tại sao việc triển khai
condition_variable_any::notify_one
vàcondition_variable::notify_one
khác nhau? Có lẽcondition_variable::notify_one
yêu cầu bảo vệ thủ công nhưngcondition_variable_any::notify_one
thì không? Có lỗi libstdC++ không?
Cảm ơn! Điều đó đã giúp tôi rất nhiều. Espeically trả lời cho 2 và 3 - điểm tốt về atomicity, và bên trong thứ mà sử dụng mutex anyway. Nhân tiện, bạn có thể thêm liên kết vào pthread_cond_wait http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cond_wait.html để cho thấy rằng triển khai phổ biến nhất chỉ hoạt động với mutex riêng của nó trong nội bộ. Bạn có thể vui lòng làm rõ chính xác những gì bạn có nghĩa là trên "có một số mã khá tinh tế ở đó." – qble
Về 1. - có thể không bị khóa condition_variable :: notify_one dẫn đến thông báo bị nhỡ? I E. thread # 1 làm công việc dưới mutex, gửi kết quả, mở khóa mutex, [trong khi đó] thread # 2 khóa mutex nhưng chưa gọi là wait, [whilewhile] thread # 1 gọi notify_one, [whilewhile] thread # 2 calls wait - notification bị mất. – qble
Đó không phải là thông báo bị mất, đó là chủ đề chờ đợi không kiểm tra biến vị ngữ điều kiện trước khi chờ. Khóa mutex không giúp được tình huống đó, thông báo vẫn có thể đến trước khi chuỗi chờ đợi khóa tiếng mutex. Bạn ** phải ** kiểm tra biến vị ngữ liên quan khi đợi trên biến điều kiện –