在用C#写一个程序时偶然碰到了一个问题,最开始我的程序是使用两个线程进行的,其中一个线程完成两个任务,一边不停地接收数据,一边通将接收到的数据发送出去。这两个任务是放在一个循环中的,即收一个发送一个,边收边发。发现一个问题,如果发送时被阻塞,整个线程都将被阻塞,势必将影响到正常地接收数据。于是想将这两个任务分别放到两个不同的线程中。这样,就引入了两个线程同步的问题。、
C#提供lock方法,天经地义地,想到同步就应该想到锁。但是仔细想想却又带来一个问题,如果发送线程被阻塞,不会释放锁,同样将阻塞接收线程。仔细想想,这两个线程其实地位是不一样的。一为主,一为次。次线程是必须依赖于主线程的。没有主线程接收到的数据,次线程也不能发送数据出去,类似于Producer-Consumer问题。对于这种不平等的情况,用锁是不恰当的。在Posix的系统当中,我们可以用semaphore来解决这个问题的。那么在C#中我们该怎么办呢? ManualResetEvent,三个方法: WaitOne(),阻塞等待有线程设置该信号; Set(),设置信号,通知阻塞线程不用阻塞了; Reset(),重设信号,WaitOne有要被阻塞了。 所以,我最后采取了如下策略。 用false初始化一个ManualResetEvent实例,false意味着调用WaitOne的线程将被阻塞至Set后。 接收线程 (Producer) loop { 接收数据; Set(); //设置信号 } 发送线程 (Consumer) loop { WaitOne(); //等待信号被set 发送数据; Reset(); //自己阻塞自己 } |
C#中使用ManualResetEvent (阻塞->激活->阻塞->激活.......)
最新推荐文章于 2024-05-28 11:43:13 发布