为什么以下代码有竞争条件?
static int i=0;
void some_fun()
{
++i;
if(2==i)
{
printf("some message");
}
}
答案 0 :(得分:1)
假设从多个线程调用此函数,它具有竞争条件,因为变量i
具有静态存储持续时间并且它在所有线程之间共享,因此多个线程可以在它们之间竞争以修改此变量。
问题是在多个线程之间共享一个相同的变量,而不像每个线程一个本地/自动变量。
如果你想避免竞争条件,你需要使用同步结构来同步对这个共享变量的访问,这里最简单和最相关的是互斥。
答案 1 :(得分:0)
Race condition
。
在您的代码中,共享资源是i变量。通常,我们称之为critical section
。
因此,如果此代码同时由多个线程或进程访问,并对其进行修改。例如,它们会增加一个,减少一个。因此,数据将不一致。
希望这有帮助:)
答案 2 :(得分:0)
假设从多个线程调用此函数,则需要保护静态变量i。 这可以通过前面提到的锁来完成,或者在这种情况下使用更有效的原子增量操作。 如果您使用的是gcc编译器,它看起来像这样:
static int i=0;
void some_fun()
{
int local_i = __sync_add_and_fetch(&i, 1);
if(2==local_i)
{
printf("some message");
}
}
__sync_add_and_fetch()函数将第二个参数添加到第一个参数并返回总和。所有这些都是作为一个原子操作。这比抓住和释放锁更有效
答案 3 :(得分:0)
我认为您正在谈论的种族是关于打印消息。不是吗?
好。
也许有人说,如果两个线程同时调用some_fun
,则只会打印一条消息。
但是,在特殊情况下,您将看到该消息两次。
void some_fun()
{
++i;
// <- Assume, The value of i is 2, and program counter of both threads are here
if(2==i)
{
printf("some message");
}
}
现在,假设线程#1检查i==2
并打印消息。并且CPU的控制权给了线程#2,然后该线程检查i==2
并再次打印该消息。
有许多解决方案可以锁定和同步此例程,例如Mutex,以达到以下目标:
void some_fun()
{
if(atomic_increment_and_test(i, 2))
{
printf("some message");
}
}