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}");
  • 相关阅读:
    JS提取子字符串函数比较
    js事件定义方式和获取事件对象event总结
    让body的clientHeight与html的clientHeight相等的方法
    关于原型链和继承问题的思考:为什么不能直接把父类的prototype赋值给子类的prototype
    [javascript权威指南笔记02]Throw语句和异常处理机制try/catch/finally
    转载:javascript语句标签
    转:JS中强大的正则表达式
    分享我常用的Javascript工具函数
    对prototype,instanceof和constrctor的理解
    xml基础知识总结和回顾
  • 原文地址:https://www.cnblogs.com/crazyghostvon/p/AutoResetEvent.html
Copyright © 2011-2022 走看看