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}");
  • 相关阅读:
    C/C++ 编程中的内存屏障(Memory Barriers) (1)
    ubuntu 10.04 源
    内存屏障(经典)
    VMware设置桥接上网
    C/C++ 编程中的内存屏障(Memory Barriers) (2)
    寒假Day55:指针
    寒假Day54:poj2378Tree Cutting没用树形dp写的树的题dfs
    寒假Day50:CodeForces1324CFrog Jumps思维
    寒假Day50:51nod3047位移运算
    寒假Day53:Codeforces519B水题
  • 原文地址:https://www.cnblogs.com/crazyghostvon/p/AutoResetEvent.html
Copyright © 2011-2022 走看看