C++ 如果';是否以原子方式重新更改检查值?

C++ 如果';是否以原子方式重新更改检查值?,c++,multithreading,locking,mutex,condition-variable,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_

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

// 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,那么互斥体是否有任何用途(除了pthreads和其他api要求您传入互斥体之外)?是否使用保护状态来实施该条件?如果不是,那么这样做安全吗

// The writer
atomic_set(protected_by_mutex_var, desired_value);
some_condition.notify_all();

作者从未直接与读者的互斥体交互?请注意,“protected_by_mutex_var”名称已不再适用(不再受互斥保护)。如果是这样,不同的读卡器是否有必要使用相同的互斥锁?

想象一下以下场景:

| 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会等待可能永远不会出现的通知。 因为作用于条件的语句不是变量read/atomic集合的一部分,所以这表示竞争条件


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

当然:p等待条件的行为不像poll()。“因为作用于条件的语句不是变量读取/原子集的一部分,这就产生了竞争条件。”请你再详细解释一下这个说法好吗?”Anisha Kaul:现在我们来考虑一下读者代码吧。在本例中,作用于条件的语句是“some_condition.wait(some_mutex)”,变量读取发生在“if(protected_by_mutex_var!=所需的_值)”中。我想说的是,没有什么能保证另一个线程不会在这两个操作之间中断——它们不是“在一起”/“原子的”;或者正如我前面所说,等待不是变量读取的“一部分”。类似地,对于编写器线程,对于原子_set调用和some_condition.notify_all()调用,我会添加一个异常:如果接收线程能够检测到值的设置时间(例如,如果它是一个原子递增的计数器,并且接收线程缓存最后看到的值以进行比较),那么您可以通过等待超时来解决竞争条件。如果您的超时足够重要,您可以捕获条件变量的大部分好处(仍然将大部分时间用于睡眠)条件变量的全部要点是它们使“检查谓词、解锁互斥锁和睡眠”成为原子。