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信号,而不应该退出。
    所以要想用上这个知识点在程序中,还需要改进不少。这个问题上次处理上位机时碰到,当时已经知道这个问题,今天因为上边的写法中,参数和加了一个循环,
    导致自己出现错觉了,以为这种写法就可以给信号执行,没信号不执行,执行完之后线程挂起而不是退出的功能

  • 相关阅读:
    (转)const变量通过指针修改问题
    sleep wait yeild join
    做事贵在坚持
    我的学习进度
    织梦dedecms后台添加图片style全部都变成st<x>yle的解决办法
    调用DEDE日期时间格式整理大全
    Arcgis andoid开发之应用百度地图接口实现精准定位与显示
    jquery自定义插件——window的实现
    lzugis—搭建属于自己的小型的版本控制SVN
    lzugis——Arcgis Server for JavaScript API之自定义InfoWindow
  • 原文地址:https://www.cnblogs.com/zuochanzi/p/6078424.html
Copyright © 2011-2022 走看看