2010-03-27 34 views
15

这里是使用条件变量的典型方式:如果您要自动更改选中的值,条件变量是否仍然需要互斥锁?

// 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被设置原子比方说,一个比较并交换指令,并互斥任何目的(比并行线程等其他API需要你传递一个互斥体)?它是用来保护状态的吗?如果不是,那么这样做是否安全?:

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

作者从来没有直接与读者的互斥体进行交互?请注意,'protected_by_mutex_var'这个名字已经不再适合了(它不再受mutex保护)。如果是这样,甚至有必要让不同的读者使用相同的互斥量?

+1

条件变量的整点是他们让“检查谓词,解锁互斥体,和睡眠“原子。 – 2011-08-28 12:17:13

回答

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

使用互斥有效地使这些行动分不开的(假设所有访问变量举止得体和锁定互斥。)

+0

当然:p等待条件不像poll()。 – 2010-03-28 07:57:43

+0

*“因为作用于条件的语句不是变量读/原子集的一部分,所以会出现竞争条件。”*您是否会再次详细解释此声明? – 2012-05-22 04:54:12

+0

@Anisha Kaul:我们现在只考虑读者代码。在这种情况下,作用于条件的语句是“some_condition.wait(some_mutex)”,变量读取发生在“if(protected_by_mutex_var!= desired_value)”中。我想说的是,没有什么能保证另一个线程不会在这两个操作之间中断 - 它们不是“一起”/“原子”的;或者如前所述,等待不是“变量读取的一部分”。编写器线程同样适用于atomic_set调用和some_condition.notify_all()调用。 – 2012-05-22 17:01:25

相关问题