首页
归档
关于
友情链接
Search
1
clash for windows允许局域网连接,TAP和TUN模式
98,369 阅读
2
使用emby打造个人影视媒体库
21,326 阅读
3
解决kodi的emby插件无法找到文件...相对路径、绝对路径问题
10,403 阅读
4
Ubuntu to go/Linux to go/将linux系统安装到u盘或移动硬盘
8,076 阅读
5
魔改版rclone挂载世纪互联onedrive
4,980 阅读
技术
软件
文章
其他
登录
Search
标签搜索
sql
代理
sqlserver
vps
onedrive
软件
Oracle
magisk
onelist
世纪互联rclone
世界x流大学.com
transmission
Transmission Remote GUI
pt
ftp
emby插件
emby for kodi插件
qBittorrent
emby
nfo
旁逸斜出
累计撰写
35
篇文章
累计收到
132
条评论
首页
栏目
技术
软件
文章
其他
页面
归档
关于
友情链接
搜索到
1
篇与
C#
的结果
2022-11-28
C#AutoResetEvent和ManualResetEvent介绍
AutoResetEvent和ManualResetEvent是c#用来线程同步的。AutoResetEvent参考:https://learn.microsoft.com/zh-cn/dotnet/api/system.threading.autoresetevent?view=net-7.0Set():将事件设置为已发送信号状态,对于AutoResetEvent来说允许一个正在等待的线程继续执行。如果没有线程在等待,将保持无限期有信号状态。WaitOne():处于无信号状态时,阻塞当前线程直到接收到了信号量如果线程在处于信号状态时AutoResetEvent调用WaitOne,则线程不会阻塞。AutoResetEvent立即释放线程并返回到无信号状态。也就是说如果没有线程在WaitOne,先执行了Set,会导致后调用的第一次WaitOne失效不阻塞,第二次调用WaitOne阻塞会生效using System; using System.Threading; namespace AutoResetEvent_Examples { class MyMainClass { const int numIterations = 100; static AutoResetEvent myResetEvent = new AutoResetEvent(false); static int number; static void Main() { //定义线程并启动,MyReadThreadProc方法接收到信号量后读取当前线程的名字和number并打印 Thread myReaderThread = new Thread(new ThreadStart(MyReadThreadProc)); myReaderThread.Name = "ReaderThread"; myReaderThread.Start(); for(int i = 1; i <= numIterations; i++) { Console.WriteLine("Writer thread writing value: {0}", i); number = i; //Signal that a value has been written. //调用Set()后MyReadThreadProc()从WaitOne()继续执行 myResetEvent.Set(); //Give the Reader thread an opportunity to act. Thread.Sleep(1); } //Terminate the reader thread. myReaderThread.Abort(); } static void MyReadThreadProc() { while(true) { //The value will not be read until the writer has written // at least once since the last read. myResetEvent.WaitOne(); Console.WriteLine("{0} reading value: {1}", Thread.CurrentThread.Name, number); } } } }官网拷贝的代码,只有当Main()中的for循环调用myResetEvent.Set(),MyReadThreadProc()才会收到信号来读取当前线程的名字,否则就会一直停在myResetEvent.WaitOne()而不会继续向后执行。ManualResetEvent参考:https://learn.microsoft.com/zh-cn/dotnet/api/system.threading.manualresetevent?view=net-7.0Set():将事件设置为已发送信号状态,对于ManualResetEvent来说允许所有正在等待的线程继续执行Reset():设置事件无信号,使能够继续阻塞线程using System; using System.Threading; public class Example { // mre is used to block and release threads manually. It is // created in the unsignaled state. private static ManualResetEvent mre = new ManualResetEvent(false); static void Main() { Console.WriteLine("\nStart 3 named threads that block on a ManualResetEvent:\n"); //定义三个线程 for(int i = 0; i <= 2; i++) { Thread t = new Thread(ThreadProc); t.Name = "Thread_" + i; t.Start(); } Thread.Sleep(500); Console.WriteLine("\nWhen all three threads have started, press Enter to call Set()" + "\nto release all the threads.\n"); Console.ReadLine(); //给信号使ThreadProc()中的WaitOne()之后的代码执行 mre.Set(); Thread.Sleep(500); Console.WriteLine("\nWhen a ManualResetEvent is signaled, threads that call WaitOne()" + "\ndo not block. Press Enter to show this.\n"); Console.ReadLine(); for(int i = 3; i <= 4; i++) { Thread t = new Thread(ThreadProc); t.Name = "Thread_" + i; t.Start(); } //ManualResetEvent在调用Set()之后,WaitOne()并不会阻塞线程,要想阻塞线程,需要调用Reset()使没有信号,才能够继续阻塞线程 Thread.Sleep(500); Console.WriteLine("\nPress Enter to call Reset(), so that threads once again block" + "\nwhen they call WaitOne().\n"); Console.ReadLine(); //调用Reset()后继续阻塞线程 mre.Reset(); // Start a thread that waits on the ManualResetEvent. Thread t5 = new Thread(ThreadProc); t5.Name = "Thread_5"; t5.Start(); Thread.Sleep(500); Console.WriteLine("\nPress Enter to call Set() and conclude the demo."); Console.ReadLine(); mre.Set(); // If you run this example in Visual Studio, uncomment the following line: Console.ReadLine(); } private static void ThreadProc() { string name = Thread.CurrentThread.Name; Console.WriteLine(name + " starts and calls mre.WaitOne()"); mre.WaitOne(); Console.WriteLine(name + " ends."); } } /* Start 3 named threads that block on a ManualResetEvent: Thread_0 starts and calls mre.WaitOne() Thread_1 starts and calls mre.WaitOne() Thread_2 starts and calls mre.WaitOne() When all three threads have started, press Enter to call Set() to release all the threads. Thread_1 ends. Thread_0 ends. Thread_2 ends. When a ManualResetEvent is signaled, threads that call WaitOne() do not block. Press Enter to show this. Thread_3 starts and calls mre.WaitOne() Thread_3 ends. Thread_4 starts and calls mre.WaitOne() Thread_4 ends. Press Enter to call Reset(), so that threads once again block when they call WaitOne(). Thread_5 starts and calls mre.WaitOne() Press Enter to call Set() and conclude the demo. Thread_5 ends. */ 简单总结一下二者区别:1.AutoResetEvent调用Set只给一个正在WaitOne的线程信号使之继续执行,ManualResetEvent调用Set会给所有正在WaitOne的线程信号使之继续执行2.在调用Set后ManualResetEvent将保持有信号状态,WaitOne将失效,不再进行线程阻塞,需要重新阻塞的话要调用Reset,但AutoResetEvent(在已经有线程WaitOne的情况下)会自动返回到无信号状态。
2022年11月28日
157 阅读
0 评论
0 点赞