zoukankan      html  css  js  c++  java
  • AutoResetEvent信号锁 waitone set 执行一次线程退出 挺不爽的地方

      下边有个 循环调用线程写奇偶数的程序

       class TheadTest
        {
            //定义一个Stream对象接收打开文件  
            private FileStream st;
            //构造方法  
            public TheadTest()
            {
            }
            public void Start()
            {
                //定义两个信号锁  
                AutoResetEvent ateA = new AutoResetEvent(false);
                AutoResetEvent ateB = new AutoResetEvent(false);
                //把信号锁加入到List中  
                List<AutoResetEvent> lst = new List<AutoResetEvent>();
                lst.Add(ateA);
                lst.Add(ateB);
    
                //定义带参数的输出偶数线程  
                Thread thrEven = new Thread(new ParameterizedThreadStart(OutPutEven));
                thrEven.Name = "偶数线程";
                //把两个信号锁传入线程  
                thrEven.Start(lst);
    
                //定义带参数的输出奇数线程  
                Thread thrOdd = new Thread(new ParameterizedThreadStart(OutPutOdd));
                thrOdd.Name = "极数线程";
                thrOdd.Start(lst);
            }
    
            private void OutPutEven(object lst)
            {
                AutoResetEvent ateA = (lst as List<AutoResetEvent>)[0];
                AutoResetEvent ateB = (lst as List<AutoResetEvent>)[1];
    
                for (int i = 0; i < 100; i += 2)
                {
                    //设置本线程为无信号  
                    ateA.WaitOne();
                    //输出  
                    Console.WriteLine(i);
                    //st = File.Open(@"C:/file.txt", FileMode.Open);      //用来测试同时访问文件系统的  
                    //st.Close();  
                    ateB.Set();  //设置输出奇数线程有信号  
                    //Thread.Sleep(500);  
                }
            }
            private void OutPutOdd(object lst)
            {
                AutoResetEvent ateA = (lst as List<AutoResetEvent>)[0];
                AutoResetEvent ateB = (lst as List<AutoResetEvent>)[1];
                //设置偶数线程先输出  
                ateA.Set();
                for (int i = 1; i < 100; i += 2)
                {
                    //设置本线程为无信号  
                    ateB.WaitOne();
                    Console.WriteLine(10000);
                    //st = File.Open(@"C:/file.txt", FileMode.Open);     //用来测试同时访问文件系统的  
                    //st.Close();  
                   ateA.Set(); //设置输出偶数线程有信号  
                    //Thread.Sleep(500);  
               }
            }
        }
    

      

    此时两个线程执行方法都在循环中没问题 ,程序是交互进行的,ateA 先执行,然后waitone ,等待ateB执行完发送set信号。

    把其中一个循环去掉,

    // for (int i = 1; i < 100; i += 2)
             //   {
                    //设置本线程为无信号  
                    ateB.WaitOne();
                    Console.WriteLine(10000);
                    //st = File.Open(@"C:/file.txt", FileMode.Open);     //用来测试同时访问文件系统的  
                    //st.Close();  
                   ateA.Set(); //设置输出偶数线程有信号  
                    //Thread.Sleep(500);  
            //   }
    运行结果:

    
    
    
    就运行了三行拉倒了,而且是
    ateA 运行了两次,
    ateB运行了一次。  没有循环只运行了一次,线程就结束了。
    ateA 的循环即使发送

    ateB.set()信号也没用了,线程已经关闭了,运行一次就关闭了,当然应该考虑到线程启动关闭的运行效率,应该就是这么个规矩,线程启动要执行哪个程序,执行完毕,
    、线程自动退出。实际运行中,这里有些理解上挺不爽的,不知道别人怎么样。
    从理解的角度上讲,线程应该一直在那启动着,给予set信号,线程执行程序开始运行,执行完后等待下次set信号,而不应该退出。
    所以要想用上这个知识点在程序中,还需要改进不少。这个问题上次处理上位机时碰到,当时已经知道这个问题,今天因为上边的写法中,参数和加了一个循环,
    导致自己出现错觉了,以为这种写法就可以给信号执行,没信号不执行,执行完之后线程挂起而不是退出的功能

  • 相关阅读:
    ubuntu12.04 死机 卡屏 画面冻结解决方案
    Install Firefox 20 in Ubuntu 13.04, Ubuntu 12.10, Ubuntu 12.04, Linux Mint 14 and Linux Mint 13 by PPA
    ListView1.SelectedItems.Clear()
    android studio 下载地址
    jquery.slider.js jquery幻灯片测试
    jquery.hovermenu.js
    jquery.tab.js选项卡效果
    适配 placeholder,jquery版
    jquery.autoscroll.js jquery自动滚动效果
    将 Google Earth 地图集成到自己的窗体上的 简单控件
  • 原文地址:https://www.cnblogs.com/zuochanzi/p/6078424.html
Copyright © 2011-2022 走看看