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

AutoResetEvent信号锁 waitone set 执行一次线程退出 挺不爽的地方的相关文章

13 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件  queue队列 生产者消费者模型 Queue队列 开发一个线程池

本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Queue队列 开发一个线程池 进程 语法 进程间通讯 进程池 操作系统发展史 手工操作(无操作系统) 1946年第一台计算机诞生--20世纪50年代中期,还未出现操作系统,计算机工作采用手工操作方式. 手工操作程序员将对应于程序和数据的已穿孔的纸带(或卡片)装入输入机,然后启动输入机把

python多线程之线程锁二(同一时间一个线程获得2把线程锁)

#coding:utf-8 '''线程锁''' import threading import time num = 0 #全局变量 num2 = 0 def runs():     time.sleep(1)     global num #在函数内部要对全局变量进行更改,需要进行声明     global num2     lock.acquire() #在操作时锁住,防止其他线程在同一时间对num变量进行加1,从而确保数据在同一时间确保只有一个线程对它进行更改,不然造成数据不正确     

CPU的最小执行单位是线程,协程不需要qt支持...直接用现成的协程库就行了

协程也就在I/O操作上才有优势,Qt事件循环,本事很多I/O已经是异步了,利用好异步(虽然都说异步有点反人类思维).因为CPU的执行最小单位是线程,协程也只是在其之上又调度而已. 我的意思是利用好异步的优势.协程是程序级别的调度,对于CPU执行来说,没任何优势的. CPU的最小执行单位是线程,单线程里十万个协程,也就一个在工作,利用不了并行优势.对于高运算的程序,协程除了增加调度开销并没有优势的.对于I/O操作较多的程序才有用,因为I/O太慢.而对应I/O操作,异步相对与协程开销更小,效率也更高

codeigniter 脚本执行超过300s超时退出问题

直接看代码, file:system/core/CodeIgniter.php /* 102  * ------------------------------------------------------ 103  *  Set a liberal script execution time limit 104  * ------------------------------------------------------ 105  */ 106     if (function_exis

QXDM安装执行失败(意外退出代码:-1073741515)问题

下了个QXDM,安装版本是QXDM.WIN.04.00.182.Installer 常规的安装,然后弹出意外退出提示: 此时尝试进入已创建的QXDM目录,运行DownloadFile.exe 提示有相关动态库文件丢失 先尝试从网上下载个MSVCR120.dll放到系统文件夹里,重试安装,没有成功:于是打算再安装个Visual C++ 2013运行库看看.先后下载并安装了vcredist_x64和vcredist_x86,终于可以正常安装QXDM: 结论:通过安装Visual C++ 2013 (

bat命令之执行脚本后不退出窗口

https://www.jianshu.com/p/efc32cb3ba9f 一般我们的解决办法是在最后加上pause命令让它暂停执行以达到不退出的目的: @echo on tasklist /fi "imagename eq nginx.exe" pause 进一步,如果我们还有需求,在得到结果后继续输入命令,比如停掉 nginx,pause 命令就不行了. @echo on tasklist /fi "imagename eq nginx.exe" @cmd /

c#中Lock(锁)的研究以及跨线程UI的操作

本文只针对C#中,多线程同步所用到的锁(lock)作为研究对象.由于想更直观的显示结果,所以,在做demo的时候,就把多线程通过事件操作UI的代码也写了出来,留作备忘和分享吧. 其实多线程的同步,使用同步锁的方法用了好多次,今天无意中看到MSDN中,建议用: 1 private static readonly object locker1 = new object(); 2 private readonly object locker2 = new object(); 备注:原文并没有加read

Java多线程与并发应用-(9)-锁lock+条件阻塞conditon实现线程同步通信

一. lock可以代替synchronized关键字实现互斥功能.使用方法如下: Lock l = ...; l.lock(); try { // access the resource protected by this lock } finally { l.unlock(); } 需要注意的是. 1.需要互斥的一个或多个方法要使用同一个互斥锁. 2.在被锁包含的代码块中,要使用finally块将锁释放. 二. Condition的await方法(注意不是wait方法)可以替换传统通信中的wa

线程执行流程与线程函数

1.线程的创建.终止及控制:        任何进程在启动时就已有了一个主线程,如果需要再生成线程则使用pthread_create函数,在该函数中可以指定线程的属性.线程例程.传给线程例程的参数.线程例程是一个用户自定义的函数,及线程执行的代码.当线程例程返回时,线程则结束运行,也可以显示调用pthread_exit来退出.线程在创建后可以用pthread_self函数获取线程ID.函数pthread_join使得进程等待线程的终止,调用pthread_join后进程将被挂起,直到指定的某个线