2025年ManualResetEvent 线程同步「建议收藏」

ManualResetEvent 线程同步「建议收藏」ManualResetE ManualResetE 用于线程同步 通知一个或多个线程某事件已经发生 通常用于一个线程执行的任务必须在其他线程的任务执行之前完成 ManualResetE 状态分为两种 终止状态和非终止状态 当某一任务完成时 将 ManualResetE 设置为终止状态 这样其他等待的线程 一个或多个 将开始执行自己的任务 注意 一旦它被终止

ManualResetEvent

ManualResetEvent 用于线程同步,通知一个或多个线程某事件已经发生。通常用于一个线程执行的任务必须在其他线程的任务执行之前完成。

ManualResetEvent状态分为两种:终止状态和非终止状态。当某一任务完成时,将ManualResetEvent设置为终止状态,这样其他等待的线程(一个或多个)将开始执行自己的任务。

注意:一旦它被终止,它将保持终止状态,直到它被手动重置。

代码示例:


代码

     class


Program
{




static





void


Main(


string


[] args)
{

Caclultae calc


=





new


Caclultae();
Console.WriteLine(


"


Result={0}


"


,calc.result(


234


).ToString());

Console.Read();
}
}



class


Caclultae
{




double


baseNum,firNum,secNum,thdNum;
AutoResetEvent[] autoEvents;
ManualResetEvent manualEvent;
Random Generator;



public


Caclultae()
{

autoEvents


=





new


AutoResetEvent[]
{




new


AutoResetEvent(


false


),



new


AutoResetEvent(


false


),



new


AutoResetEvent(


false


)
};
manualEvent


=





new


ManualResetEvent(


false


);
}



void


CalBase(


object


stateInfo)
{

baseNum


=


Generator.NextDouble();
Console.WriteLine(


"


BaseNum is Ok


"


);
manualEvent.Set();
}



void


CalFirst(


object


stateInfo)
{




double


preCalc


=


Generator.NextDouble();

manualEvent.WaitOne();
Console.WriteLine(


"


FirstNum begins to Calculate


"


);
firNum


=


preCalc


*


baseNum


*


Generator.NextDouble();

autoEvents[


0


].Set();
Console.WriteLine(


"


FirstNum Calculates successfully


"


);
}



void


CalSec(


object


stateInfo)
{




double


preCalc


=


Generator.NextDouble();
manualEvent.WaitOne();
Console.WriteLine(


"


SecNum begins to Calculate


"


);
secNum


=


preCalc


*


baseNum


*


Generator.NextDouble();
autoEvents[


1


].Set();
Console.WriteLine(


"


SecNum Calculates successfully


"


);
}



void


CalThird(


object


stateInfo)
{




double


preCalc


=


Generator.NextDouble();
manualEvent.WaitOne();
Console.WriteLine(


"


ThrdNum begins to Calculate


"


);
thdNum


=


preCalc


*


baseNum


*


Generator.NextDouble();
autoEvents[


2


].Set();
Console.WriteLine(


"


ThrdNum Calculates successfully


"


);
}



public





double


result(


int


seed)
{

Generator


=





new


Random(seed);
ThreadPool.QueueUserWorkItem(


new


WaitCallback(CalBase));
ThreadPool.QueueUserWorkItem(


new


WaitCallback(CalFirst));
ThreadPool.QueueUserWorkItem(


new


WaitCallback(CalSec));
ThreadPool.QueueUserWorkItem(


new


WaitCallback(CalThird));
WaitHandle.WaitAll(autoEvents);
manualEvent.Reset();



return


firNum


+


secNum


+


thdNum;
}

}

代码中,我们可以看到,CalFirst,CalSec,CalThird都在等待CalBase执行完成。当CalBase计算出BaseNum的结果之后,将ManualResetEvent变量设置为终止状态,通知其他三个任务,可以执行他们自己的任务了。

执行结果:

1).执行一次的结果:

2). 再次执行的结果:

从两次执行结果中看出,CalFirst、CalSec、CalThird的执行顺序是不一定的,也就是说 这三个的地位是相同的,都在等待CalBase执行成功,从而执行自己的任务。这也验证了 ManualResetEvent的作用,用于通知一个或多个线程某个事件发生。

编程小号
上一篇 2025-10-07 22:30
下一篇 2025-08-28 11:33

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/hz/127603.html