以下是使用条件变量的典型方法:
// The reader(s)
lock(some_mutex);
if(protected_by_mutex_var != desired_value)
some_condition.wait(some_mutex);
unlock(some_mutex);
// The writer
lock(some_mutex);
protected_by_mutex_var = desired_value;
unlock(some_mutex);
some_condition.notify_all();
但是,如果通过比较和交换指令原子地设置protected_by_mutex_var,则互斥量是否可用于任何目的(除了pthread和其他API要求您传入互斥锁)?是否保护用于实施条件的状态?如果没有,那么这样做是否安全?:
// The writer
atomic_set(protected_by_mutex_var, desired_value);
some_condition.notify_all();
作者从不直接与读者的互斥体互动?请注意,'protected_by_mutex_var'名称不再合适(它不再受互斥保护)。如果是这样,是否有必要让不同的读者使用相同的互斥锁?
答案 0 :(得分:14)
想象一下以下场景:
| Thread 1 | Thread 2 |
| if(protected_by_mutex_var != desired_value) -> true | |
| | atomic_set(protected_by_mutex_var, desired_value); |
| | some_condition.notify_all(); |
| some_condition.wait(some_mutex); | |
这种情况看到线程1正在等待可能永远不会发生的通知。 因为作用于条件的语句不是变量读/原子集的一部分,所以这呈现竞争条件。
有效地使用互斥锁会使这些操作不可分割(假设对变量的所有访问都正常运行并锁定互斥锁。)