线程同步。到底为什么这个锁是不够的同步线程 [英] Thread synchronization. Why exactly this lock isn't enough to synchronize threads

查看:215
本文介绍了线程同步。到底为什么这个锁是不够的同步线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能重复:
  <一href="http://stackoverflow.com/questions/7131979/threads-synchronization-how-exactly-lock-makes-access-to-memory-correct">Threads同步。究竟如何锁定使得对内存的访问正确?

此问题是由<一个启发href="http://stackoverflow.com/questions/7131979/threads-synchronization-how-exactly-lock-makes-access-to-memory-correct">this之一。

我们得到了以下测试类

class Test
{
    private static object ms_Lock=new object();
    private static int ms_Sum = 0;

    public static void Main ()
    {
        Parallel.Invoke(HalfJob, HalfJob);
        Console.WriteLine(ms_Sum);
        Console.ReadLine();
    }

    private static void HalfJob()
    {
        for (int i = 0; i < 50000000; i++) {
            lock(ms_Lock) { }// empty lock

            ms_Sum += 1;
        }
    }
}

实际结果非常接近预期值100 000 000(50 000 000×2,因为2个循环是在同一时间运行),大约有600 - 200的区别(错误约为0.0004%,我的机器上,这是非常低)。同步没有其他办法可提供近似这样的方式(它或者是更大的失误%以上的正确率100%)

Actual result is very close to expected value 100 000 000 (50 000 000 x 2, since 2 loops are running at the same time), with around 600 - 200 difference (mistake is approx 0.0004% on my machine which is very low). No other way of synchronization can provide such way of approximation (its either a much bigger mistake % or its 100% correct)

我们目前理解的preciseness这样的水平是因为节目的运行在下面的方式:

We currently understand that such level of preciseness is because of program runs in the following way:

时间不多左到右,和2个线程重新由两排psented $ P $。

Time is running left to right, and 2 threads are represented by two rows.

其中

  • 黑匣子重新presents获取,保持和释放的过程中,

  • black box represents process of acquiring, holding and releasing the

锁加上重新presents加法运算(模式重新presents规模上 我的电脑,锁定需要近似长于20次加)

lock plus represents addition operation ( schema represents scale on my PC, lock takes approximated 20 times longer than add)

另外锁定提供了完整的内存栅栏。

Also lock provides full memory fence.

所以,现在的问题是:如果上面的架构重新presents到底是怎么回事,什么是如此之大的错误原因(现在它的大的原因的模式看起来很强大syncrhonization模式)?我们可以理解在边界1-10之间的差异,但其显然没有错误的唯一原因?我们不能看到,当写入ms_Sum可以发生在同一时间,造成错误。

So the question now is: if above schema represents what is going on, what is the cause of such big error (now its big cause schema looks like very strong syncrhonization schema)? We could understand difference between 1-10 on boundaries, but its clearly no the only reason of error? We cannot see when writes to ms_Sum can happen at the same time, to cause the error.

编辑:很多人都喜欢跳到快的结论。我知道什么是同步的,而上面的结构是不是一个真正的或接近,如果我们需要正确的结果同步线程好方法。在海报的一些信仰或者先阅读链接的答案。我并不需要一种方法来同步2个线程并行执行加法,我在探索这个奢侈而有效,比的任意的可能和近似的替代方案,同步结构(它不同步,在一定程度上使公司的没有意义类似建议)

many people like to jump to quick conclusions. I know what synchronization is, and that above construct is not a real or close to good way to synchronize threads if we need correct result. Have some faith in poster or maybe read linked answer first. I don't need a way to synchronize 2 threads to perform additions in parallel, I am exploring this extravagant and yet efficient , compared to any possible and approximate alternative, synchronization construct (it does synchronize to some extent so its not meaningless like suggested)

推荐答案

这是一个非常紧密的循环与里面没有太多的事情,所以 ms_Sum + = 1 有由并行线程执行的只是错误的时刻一个合理的机会。

This is a very tight loop with not much going on inside it, so ms_Sum += 1 has a reasonable chance of being executed in "just the wrong moment" by the parallel threads.

为什么你曾经写一个code这样的做法呢?

Why would you ever write a code like this in practice?

为什么不:

lock(ms_Lock) { 
    ms_Sum += 1;
}

或者只是:

Interlocked.Increment(ms_Sum);

- 编辑 -

这是为什么你会看到,尽管锁定的记忆障碍方面的错误一些意见...想象一下以下情形:

Some comments on why would you see the error despite memory barrier aspect of the lock... Imagine the following scenario:

  • 在线程A进入锁定,离开锁定,然后是pre-抢占由操作系统调度。
  • 在线程B进入和离开锁定(可能是一次,可能不止一次,可能是数百万次)。
  • 在这一点上,线程A再次计划。
  • 在A和B命中 ms_Sum + = 1 的同时,导致部分增量丢失(因为增量=负载+加+实体店)。
  • Thread A enters the lock, leaves the lock and then is pre-empted by the OS scheduler.
  • Thread B enters and leaves the lock (possibly once, possibly more than once, possibly millions of times).
  • At that point the thread A is scheduled again.
  • Both A and B hit the ms_Sum += 1 at the same time, resulting in some increments being lost (because increment = load + add + store).

这篇关于线程同步。到底为什么这个锁是不够的同步线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆