为什么以下代码中的竞争条件

时间:2013-03-13 06:19:34

标签: c race-condition

为什么以下代码有竞争条件?

static int i=0;
void some_fun()
{
  ++i;
  if(2==i)
  {
    printf("some message");
  }
}

4 个答案:

答案 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");
  }
}