AutoResetEvent不可靠

Posted crazyghostvon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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}");

 

第四版:到底什么++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}");

 

以上是关于AutoResetEvent不可靠的主要内容,如果未能解决你的问题,请参考以下文章

Linux 下 AutoResetEvent 的 C++ 等价物是啥?

AutoResetEvent和ManualResetEvent理解 z

《安富莱嵌入式周报》第279期:强劲的代码片段搜索工具,卡内基梅隆大学安全可靠C编码标准,Nordic发布双频WiFi6 nRF7002芯片

多线程--Task,等待用户输入AutoResetEvent

多线程的AutoResetEvent

线程同步之-旋转门AutoResetEvent