Csharp/C#教程:c# 进程之间的线程同步分享

  Mutex类、Event类、SemaphoreSlim类和ReaderWriterLockSlim类等提供了多个进程之间的线程同步。

 1、WaitHandle基类

  WaitHandle抽象类,用于等待一个信号的设置。可以根据其派生类的不同,等待不同的信号。异步委托的BeginInvoke()方法返回一个实现了IAsycResult接口的对象。使用IAsycResult接口可以用AsycWaitHandle属性访问WaitHandle基类。在调用WaitOne()方法时,线程会等待接收一个和等待句柄相关的信号:

staticvoidMain(string[]args) { Func<int>func=newFunc<int>( ()=> { Thread.Sleep(1500); return1; }); IAsyncResultar=func.BeginInvoke(null,null); intcount=0; while(true) { Interlocked.Increment(refcount); Console.WriteLine("第{0}周期循环等待结果。",count); if(ar.AsyncWaitHandle.WaitOne(100,false)) { Console.WriteLine("获得返回结果。"); break; } } intresult=func.EndInvoke(ar); Console.WriteLine("结果为:{0}",result); }

  使用WaitHandle基类可以等待一个信号的出现(WaitHandle()方法)、等待多个对象都必须发出信号(WaitAll()方法)、等待多个对象中任一一个发出信号(WaitAny()方法)。其中WaitAll()方法和WaitAny()方法时WaitHandle类的静态方法,接收一个WaitHandle参数数组。

  WaitHandle基类的SafeWaitHandle属性,其中可以将一个本机句柄赋予一个系统资源,等待该句柄,如I/O操作,或者自定义的句柄。

2、Mutex类

  Mutex类继承自WaitHandle类,提供跨多个进程同步访问的一个类。类似于Monitor类,只能有一个线程拥有锁定。在Mutex类的构造函数各参数含义:

initiallyOwned:如果为true,则给予调用线程已命名的系统互斥体的初始所属权(如果已命名的系统互斥体是通过此调用创建的);否则为false。 name:系统互斥体的名称。如果值为null,则System.Threading.Mutex是未命名的。 createdNew:在此方法返回时,如果创建了局部互斥体(即,如果name为null或空字符串)或指定的命名系统互斥体,则包含布尔值true;如果指定的命名系统互斥体已存在,则为false。该参数未经初始化即被传递。 mutexSecurity:一个System.Security.AccessControl.MutexSecurity对象,表示应用于已命名的系统互斥体的访问控制安全性。

  互斥也可以在另一个进程中定义,操作系统能够识别有名称的互斥,它由进程之间共享。如果没有指定互斥的名称,则不在不同的进程之间共享。该方法可以检测程序是否已运行,可以禁止程序启动两次。

staticvoidMain(string[]args) { //ThreadingTimer(); //TimersTimer(); boolisCreateNew=false; Mutexmutex=newMutex(false,"MyApp",outisCreateNew);//查询是否已有互斥“MyApp”存在 if(isCreateNew==false) { //已存在互斥 } }

  要打开已有互斥,可以使用Mutex.OpenExisting()方法,不需要构造函数创建互斥时需要的相同.Net权限。可以使用WaitOne()方法获得互斥的锁定,成为该互斥的拥有着。调用ReleaseMutex()方法释放互斥:

if(mutex.WaitOne())//设置互斥锁定 { try { //执行代码 } finally{ mutex.ReleaseMutex();//释放互斥 } } else { //出现问题 }

3、Semaphore类

  信号量是一种计数的互斥锁定,可以同时由多个线程使用。信号量可定义允许同时访问受旗语锁定保护的资源的线程个数。Semaphore和SemaphoreSlim两个类具有信号量功能。Semaphore类可以指定名称,让其在系统资源范围内查找到,允许在不同的进程之间同步。Semaphore类是对较短等待时间进行优化了的轻型版本。

staticvoidMain() { inttaskCount=6; intsemaphoreCount=3; Semaphoresemaphore=newSemaphore(semaphoreCount,semaphoreCount,"Test");//创建计数为3的信号量 /*第一个参数为初始释放的锁定数,第二个参数为可锁定的总数。如果第一个参数小于第二个参数,其差值就是已分配线程的计量数。 *第三个参数为信号指定的名称,能让它在不同的进程之间共享。 */ vartasks=newTask[taskCount]; for(inti=0;i<taskCount;i++) { tasks[i]=Task.Run(()=>TaskMain(semaphore));//创建6个任务 } Task.WaitAll(tasks); Console.WriteLine("Alltasksfinished"); } //锁定信号的任务 staticvoidTaskMain(Semaphoresemaphore) { boolisCompleted=false; while(!isCompleted)//循环等待被释放的信号量 { if(semaphore.WaitOne(600))//最长等待600ms { try { Console.WriteLine("Task{0}locksthesemaphore",Task.CurrentId); Thread.Sleep(2000);//2s后释放信号 } finally { Console.WriteLine("Task{0}releasesthesemaphore",Task.CurrentId); semaphore.Release();//释放信号量 isCompleted=true; } } else { //超过规定的等待时间,写入一条超时等待的信息 Console.WriteLine("Timeoutfortask{0};waitagain",Task.CurrentId); } } }

  上述就是C#学习教程:c# 进程之间的线程同步分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/903731.html

(0)
上一篇 2021年10月21日
下一篇 2021年10月21日

精彩推荐