多线程两个线程到达同一点

时间:2015-11-30 20:39:47

标签: multithreading

你有两个线程,一个运行函数f1(),另一个运行f2()。 有时f1从未完成,尽管看到了f2的所有打印件。 解释这怎么可能发生并提供解决方案?

int _f2_finished = 0;

Void f1()
{
    print(“f1 waiting “);
    while (!_f2_finished) {usleep(50);}
    print(“share of work”);
}

void f2()
{
   Printf(“f2 doing some stuff”);
   usleep(5*1000*1000);
   Printf(“f2 signaling finished”);
   _f2_finished = 1;
   Printf(“f2 signaled finished”);
}

我试图解决它我无法理解为什么f1()仍然停留在while循环中尽管f2打印的所有消息意味着_f2_finished都是1退出while循环?

它是C语言和Windows平台。

1 个答案:

答案 0 :(得分:2)

大多数线程模型指定访问一个线程中的对象是非法的,而另一个线程正在或可能正在修改它。它们确实提供了合法共享数据的方法,例如原子操作,互斥体等。

碰巧,在这种特殊情况下,您需要“内存可见性”保证。也就是说,确保在另一个线程中“很快”看到在一个线程中进行的更改。保证内存可见性需要禁用许多编译器优化(例如缓存寄存器中的变量值),因此只有在请求它时才能获得它。

在Windows上,您有很多选择。您可以使用CRITICAL_SECTION来保护共享值,也可以使用各种Interlocked操作。

在所有已知的Windows平台上,使用volatile在不需要原子性的情况下提供内存可见性的工作正常发生,并且在不久的将来这种情况不太可能发生变化。如果您不理解,请忽略它,只使用易于纠正并且难以像互斥锁一样出错的内容。 (因为如果你使用volatile这样没有深刻的认识,迟早你会在它发生不可靠地工作,你的代码将在最糟糕的时候最可怕的方式失败的情况下使用。)