【问题标题】:Impact of locks on multithreading performance [duplicate]锁对多线程性能的影响[重复]
【发布时间】:2018-04-29 14:01:24
【问题描述】:

我有一个简单的类,旨在玩转线程。它有一个初始化为 0 的成员变量 num,以及一个名为 modify 的方法,该方法会多次递增然后递减 num。当程序运行时,它会创建两个都运行 modify 的线程,然后启动计时器并启动线程。它使用 while 循环等待两个线程完成执行,然后停止计时器并将经过的时间打印到控制台。班级:

public class Threading
{

    public static void Main()
    {
        Threading t = new Threading();
        t.demo();
    }

    private int num = 0;

    public void doThreading()
    {

        Thread t1 = new Thread(modify);
        Thread t2 = new Thread(modify);

        t1.Start();
        t2.Start();

        Stopwatch timer = new Stopwatch();
        timer.Start();

        while (thread1.IsAlive || thread2.IsAlive)
        {

        }

        timer.Stop();
        Console.WriteLine("Took: " + timer.ElapsedMilliseconds + " milliseconds");

        Console.Read();
    }

    public void modify()
    {
        for (int i = 0; i < 1000000000; i++)
        {
            count++;
            count--;
        }
    }
}

运行程序后,由于竞态条件,num 不会为 0。当我给 modify 方法加锁,使程序运行后 num 为 0:

public void modify()
    {
        for (int i = 0; i < 1000000000; i++)
        {
            lock (this) { count++; }
            lock (this) { count--; }
        }
    }

那么程序的执行时间是原来的 8 倍。我无法弄清楚为什么它会花费这么长时间,我预计最多会花费 4 倍的时间来执行。知道为什么需要这么长时间吗?

【问题讨论】:

  • 大声笑,为什么你期望 4,而不是 8? :) 为什么你选择 4,而不是 5,不是 2,不是 11?期待这一点很奇怪。
  • 我对多线程和锁的理解非常有限,我认为既然有 2 个线程和 2 段代码,它们都在单独的锁中,那么速度会降低2. 我并没有真正考虑访问锁的开销,只是强制线程相互等待的成本,但我想用这么简单的代码访问锁的开销可能相当大
  • 好吧,问错了。应该是“lock 怎么会如此高效?”

标签: c# multithreading performance locking


【解决方案1】:
在这种情况下,

lock 可能看起来相当昂贵(您想要的只是锁定递增int,即生成count++ 原子) ;改用Interlocked

public void modify()
{
    for (int i = 0; i < 1000000000; i++)
    {
        Interlocked.Increment(ref count);
        Interlocked.Decrement(ref count); 
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多