如果您原子地更改检查值,条件变量是否仍需要互斥锁?

时间:2010-03-27 23:41:11

标签: c++ multithreading locking mutex condition-variable

以下是使用条件变量的典型方法:

// 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'名称不再合适(它不再受互斥保护)。如果是这样,是否有必要让不同的读者使用相同的互斥锁?

1 个答案:

答案 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正在等待可能永远不会发生的通知。 因为作用于条件的语句不是变量读/原子集的一部分,所以这呈现竞争条件。

有效地使用互斥锁会使这些操作不可分割(假设对变量的所有访问都正常运行并锁定互斥锁。)