AutoResetEvent不可靠

如下的代码,最后的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}");

猜你喜欢

转载自www.cnblogs.com/crazyghostvon/p/AutoResetEvent.html
今日推荐