zoukankan      html  css  js  c++  java
  • AutoResetEvent不可靠 ++i, i++

    如下的代码,最后的cnt 居然不为0?

    哪里的bug?

    t2跑的太快了。

                AutoResetEvent m = new AutoResetEvent(false);
                int i = 0;
                int[] data = new int[0x100000];
                Task t1 = Task.Run(() =>
                {
                    Console.WriteLine("t1 run");
                    while (i < 0x0fffff)
                    {
                        ++i;
                        m.WaitOne();
                    }
                    Console.WriteLine("t1 done");
    
                });
    
                Task t2 = Task.Run(() =>
                {
                    Console.WriteLine("t2 run");
                    while (i < 0x0fffff)
                    {
                        data[i] = i;
                        m.Set();
                    }
                    Console.WriteLine("t2 done");
    
                });
    
                Task.WaitAll(t1,t2);
    
                int cnt = 0;
                int min = 0x0fffff;
                for (int j = 0; j < 0x0fffff; ++j)
                {
                    if (data[j] != j)
                    {
                        min = Math.Min(min, j);
                        cnt++;
                    }
                }
    
                Console.WriteLine(cnt *1.0 / 0x0fffff);

    再来一个AutoResetEvent就好了。

                AutoResetEvent m1 = new AutoResetEvent(true);
                AutoResetEvent m2 = new AutoResetEvent(false);
                int i = 0;
                int[] data = new int[0x100000];
                Task t1 = Task.Run(() =>
                {
                    Console.WriteLine("t1 run");
                    while (i < 0x0fffff)
                    {
                        m1.WaitOne();
                        ++i;
                        m2.Set();
                    }
                    Console.WriteLine("t1 done");
    
                });
    
                Task t2 = Task.Run(() =>
                {
                    Console.WriteLine("t2 run");
                    while (i < 0x0fffff)
                    {
                        m2.WaitOne();
                           data[i] = i;
                        m1.Set();
                    }
                    Console.WriteLine("t2 done");
    
                });
    
                Task.WaitAll(t1,t2);
    
                int cnt = 0;
                int min = 0x0fffff;
                for (int j = 0; j < 0x0fffff; ++j)
                {
                    if (data[j] != j)
                    {
                        min = Math.Min(min, j);
                        cnt++;
                    }
                }
    
                Console.WriteLine(cnt *1.0 / 0x0fffff);

    case1的修改版:结果任然不为0,奇怪怪

                AutoResetEvent m1 = new AutoResetEvent(false);
                int i = 0;
                int[] data = new int[0x100000];
                Task t1 = Task.Run(() =>
                {
                    Console.WriteLine("t1 run");
                    while (i < 0x0fffff)
                    {
                        m1.WaitOne();
                        ++i;
                    }
                    Console.WriteLine("t1 done");
    
                });
    
                Task t2 = Task.Run(() =>
                {
                    Console.WriteLine("t2 run");
                    while (i < 0x0fffff)
                    {
                        data[i] = i;
                        m1.Set();
                    }
                    Console.WriteLine("t2 done");
    
                });
    
                Task.WaitAll(t1, t2);
    
                int cnt = 0;
                int min = 0x0fffff;
                for (int j = 0; j < 0x0fffff; ++j)
                {
                    if (data[j] != j)
                    {
                        min = Math.Min(min, j);
                        cnt++;
                        Console.WriteLine($"data[{j}]: {data[j]}");
                    }
                }
    
                Console.WriteLine($"min: {min}, count: {cnt}, {cnt * 1.0 / 0x0fffff}");

    第四版:到底什么++i, 什么是i++?

                AutoResetEvent m1 = new AutoResetEvent(false);
                int[] data = new int[0x100000];
                Task t1 = Task.Run(() =>
                {
                    Console.WriteLine("t1 run");
                    while (i < 0x0fffff)
                    {
                        m1.WaitOne();
                        i++;
                    }
                    Console.WriteLine("t1 done");
    
                });
    
                Task t2 = Task.Run(() =>
                {
                    Console.WriteLine("t2 run");
                    while (i < 0x0fffff)
                    {
                        data[i] = i;
                        m1.Set();
                    }
                    Console.WriteLine("t2 done");
    
                });
    
                Task.WaitAll(t1, t2);
    
                int cnt = 0;
                int min = 0x0fffff;
                for (int j = 0; j < 0x0fffff; ++j)
                {
                    if (data[j] != j)
                    {
                        min = Math.Min(min, j);
                        cnt++;
                        Console.WriteLine($"data[{j}]: {data[j]}");
                    }
                }
    
                Console.WriteLine($"min: {min}, count: {cnt}, {cnt * 1.0 / 0x0fffff}");
  • 相关阅读:
    Android5.0录屏方案
    Android点阵屏效果的控件
    Android绘制View相关的几个问题
    AndroidStudio导入第三方开源库
    第六百二十三天 how can I坚持
    第六百二十二天 how can I 坚持
    第六百二十一天 how can I 坚持
    第六百二十天 how can I 坚持
    第六百一十九天 how can I 坚持
    第六百一十八天 how can I 坚持
  • 原文地址:https://www.cnblogs.com/crazyghostvon/p/AutoResetEvent.html
Copyright © 2011-2022 走看看