并行和同步

时间:2010-10-10 10:53:22

标签: c# java .net parallel-processing task-parallel-library

想象一下,您正在多核系统中使用Parallelism。

是否可以同时执行相同的指令?

请使用以下代码:

int i = 0;

if( blockingCondition )
{
  lock( objLock )
  {
    i++;
  }
}

在我看来,似乎在具有多个内核和并行性的系统上很可能在同一时刻检查blockingCondition,导致同时尝试锁定,依此类推。这是真的吗?

如果是这样,您如何确保跨处理器同步?

此外,.net TPL是否处理此类同步?其他语言怎么样?

修改 请注意,这是关于线程的,但是任务和并行处理。

编辑2 好的,谢谢大家的信息。那么操作系统是否会确保写入内存是序列化的,确保通过易失性读取实现多核同步?

3 个答案:

答案 0 :(得分:2)

要了解其工作原理,请记住:

  1. 锁定锁定(即递增a 锁定对象上的信号量)是一个 阻止对象的操作 已被锁定。

  2. lock的两个步骤,a)检查锁定 信号量是免费的,b)实际上 锁定对象,执行 '同时' - 即他们是 单片或原子操作 远与CPU和CPU之间的关系 关注记忆。

  3. 因此,您可以看到,如果2个线程进入您的if - 块,则两个线程中的一个将获取锁定,另一个将阻塞,直到第一个线程完成if

答案 1 :(得分:1)

您关注的正是为什么我们需要像lock这样的特殊机制,而不能简单地使用布尔标志。

“同时”问题的解决方案是lock(调用Monitor.Enter())使用的算法。它涉及内存障碍和非常低级内存机制的知识,以确保没有2个线程可以同时获取锁。

注意:我只谈论.NET,而不是Java。

答案 2 :(得分:1)

这里描述的锁是objLock上的“Monitor”样式锁。正如您所指出的,在多核系统下,完全可以同时对开始进行两次“锁定”调用。但是,任何使用监视器的高级应用程序环境都会将监视器转换为semaphore请求(或者,根据您的操作系统和语言细节,互斥请求)在编译的字节代码中。

信号量在操作系统和/或硬件级别实现,更高级别的语言绑定到它们。在操作系统级别,它们被“保证”为原子级。也就是说,任何获取信号量的程序都保证是在那个时间点唯一这样做的程序。如果两个程序或程序中的两个线程同时尝试获取锁定,则会先进行(并成功),另一个进入第二个(并失败)。

此时,“如何确保同步”不再是应用程序员担心的问题,并且开始成为操作系统设计人员和硬件设计人员的问题。

它的结果是,作为一个应用程序编码器,你可以安全地假设“lock(objLock)”将是一个原子调用,无论你插入系统多少CPU。