• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

C# 线程同步的方法

c# 搞代码 4年前 (2022-01-09) 15次浏览 已收录 0个评论

一、进程内部的线程同步

1、使用lock,用法如下:

private static readonly object SeqLock = new object();

    private void Print()
    {
      lock (SeqLock)
      {
        Console.WriteLine("test");
      }
    }

特性:只能传递对象,无法设置等待超时

2、使用:InterLocked(原子操作)

其在System.Threading命名空间下,Interlocked实际是类控制计数器,从而实现进程的同步,其很容易实现生产者消费者模型

//缓冲区,只能容纳一个字符
   private static char buffer;
   //标识量(缓冲区中已使用的空间,初始值为0)
   private static long numberOfUsedSpace = 0;
   static void Main(string[] args)
   {
    //线程:写入者
    Thread Writer = new Thread(delegate ()
    {
     string str = "这里面的字会一个一个读取出来,一个都不会少,,,";
     for (int i = 0; i < 24; i++)
     {
      //写入数据前检查缓冲区是否已满
      //如果已满,就进行等待,直到缓冲区中的数据被进程Reader读取为止
      while (Interlocked.Read(ref numberOfUsedSpace) == 1)
      {
       Thread.Sleep(50);
      }
      buffer = str[i]; //向缓冲区写入数据
      //写入数据后把缓冲区标记为满(由0变为1)
      Interlocked.Increment(ref numberOfUsedSpace);
     }
    });
    //线程:读出者
    Thread Reader = new Thread(delegate ()
    {
     for (int i = 0; i < 24; i++)
     {
      //读取数据前检查缓冲区是否为空
      //如果为空,就进行等待,直到进程Writer向缓冲区中写入数据为止
      while (Interlocked.Read(ref numberOfUsedSpace) == 0)
      {
       Thread.Sleep(50);
      }
      char ch = buffer;  //从缓冲区读取数据
      Console.Write(ch);
      Interlocked.Decrement(ref numberOfUsedSpace);
     }
    });
    //启动线程
    Writer.Start();
    Reader.Start();
    Console.ReadKey();

3、使用Monitor

其中Monitor.Enter()和lock相同

      Monitor.Enter(obj){
        //Synchronized part
      }finally{
        Monitor.Exit(obj);
      }

TryEnter则可设置等待时间等

bool lockTaken=false;
      Monitor.TryEnter(obj, 500, ref lockTaken);
      if(lockTaken){
        try
        {
          //Synchronized part
        }
        finally
        {
          Monitor.Exit(obj);
        }
      }else{
        //don't aquire the lock, excute other parts
      }

二、进程间的同步

1. WaitHandle:

封装等待对共享资源进行独占访问的操作系统特定的对象。 WaitHandle:是一个抽象类,我们一般不直接用,而是用它的派生类:

AutoResetEvent、EventWaitHandle、ManualResetEvent、Mutex、Semaphore

这个抽象类的方法如下:

WaitOne(): 等待一个信号的出现,可设置超时;

WaitAll(): 等待多个信号的出现,可设置超时;

WaitAny(): 等待任意一个信号的出现,可设置超时;

2、Mutex:本文来源gao($daima.com搞@代@#码$网 与Monitor 类似,只有一个线程能够获取锁定。利用WaitOne() 获取锁定,利用ReleaseMutex() 解除锁定。构造函数使用如下:

      bool isNew = false;
      mutex = new Mutex(false, "Mutex1", out isNew);

参数1:锁创建后是否由主调线程拥有。 如果设为true,相当于调用了WaitOne(),需要释放,否则其他线程无法获取锁;


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:C# 线程同步的方法

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址