我理解保护复杂数据结构的必要性。像链表一样,有信号量。我已经看到了当一个线程修改列表而另一个线程在列表中行走时可能发生的坏事。
但这是否需要一个非常简单的数据字段,比如布尔值?在我工作的地方,我看到了很多代码,如下面的示例,或者需要通过代码审阅者添加这些代码。这真的需要吗?如果是这样,有人可以解释如果不使用信号量会出现什么问题吗?
#define TRUE 1
#define FALSE 0
static int enabled;
int is_foo_enabled(void)
{
int ret;
reserve_foo_semaphore();
ret = enabled;
release_foo_semaphore();
return ret;
}
void enable_foo(void)
{
reserve_foo_semaphore();
enabled = TRUE;
release_foo_semaphore();
}
void disable_foo(void)
{
reserve_foo_semaphore();
enabled = FALSE;
release_foo_semaphore();
}
答案 0 :(得分:1)
原子访问保证了多种功能(取决于内存模型语义) -
你对第一个不适用于布尔类型的子弹是正确的(虽然这取决于你的系统,谁知道如何在那里实现布尔值......),但其他保证仍然很重要。
答案 1 :(得分:0)
是的,它是必需的,例如你的一个线程可以检查这个值,并依赖它false
,然后它开始执行像false
这样的事情,但就在之前一些其他线程将其更改为true,并且不再需要该操作,甚至可能导致错误。另外,改变一个布尔值并不是真正的原子操作,或者至少可能不是原子操作,所以当你的线程(或者进程,如果我们谈论共享内存,例如),它将导致一个大混乱同时更改此值。基本上,当代码试图检查或更改任何共享值(甚至是布尔值)时,您需要锁定并释放互斥锁。同样在你的问题的上下文中,你只有一个int
,即使它被用作布尔值,我也不认为任何人都不需要使用互斥量来改变整数。