深入理解.Net中的线程同步之构造模式(二)内核模式2.内核模式构造物Semaphone

深入理解.Net中的线程同步之构造模式(二)内核模式构造

前言

Kernel-mode Constructs一般翻译为内核模式构造 ,
Constructs 即是一个名词也是一个动词,但是翻译为构造感觉有点像一个动词,个人感觉翻译为名词更好,毕竟是加了s的,就表示多个,动词显然不能表示多个啊,比如内核模式构造物,内核模式构造体。


环境说明
IDE:Visual Studio 2022
OS:Win10
.NET:.Net4.6.1

一、信号量是什么?

信号量是什么?记得嵌入式的时候老师说过通过0,1来控制线程的阻断和解除阻断就是信号量。这个就是信号量最基础的理解了,信号量其实是由系统内核控制的具有原子性的int变量,为0时阻塞线程,大于0时解除阻塞。

二、代码编写

1.编写一个Semaphone的锁

代码如下(示例):

  public class SemaphoreTest
    {

        public void TestStart() 
        {
        
            Console.WriteLine(" SemaphoreTest TestStart Start !");
            IntObj intObj = new IntObj();
      
            for (Int32 i = 0; i < 10; i++)
            {
            
                new TaskFactory().StartNew(() =>
                {
                    AddCount(intObj);
                    AddCount_SemaphoreLock(intObj);
                });
            }
            Console.WriteLine(" SemaphoreTest TestStart END !");
        }
        
        public void AddCount(IntObj intObj)
        {  

            intObj.num_Norml++;
            WriteLineThread(intObj);
            Thread.Sleep(500);
        }
        SemaphoreLock tLock = new SemaphoreLock(1);

        public void AddCount_SemaphoreLock(IntObj intObj)
        {
            tLock.Enter();

            intObj.num_Lock++;
            WriteLineThread_SemaphoreLock(intObj);
            Thread.Sleep(500);
            tLock.Leave();
            tLock.Leave();
        }
        public void WriteLineThread(IntObj intObj )
        {
            Thread.Sleep(200);
            ConsoleColor currentForeColor = Console.ForegroundColor;
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine($"num_Norml :{ intObj.num_Norml},{Thread.CurrentThread.ManagedThreadId}");
            Console.ForegroundColor = currentForeColor;
            Thread.Sleep(200);
        }

        public void WriteLineThread_SemaphoreLock(IntObj intObj)
        {
            Thread.Sleep(200);
            ConsoleColor currentForeColor = Console.ForegroundColor;
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine($"num_Lock:{ intObj.num_Lock},{Thread.CurrentThread.ManagedThreadId}");
            Console.ForegroundColor = currentForeColor;
            Thread.Sleep(200);
        }

    }     

2.测试Semaphone锁的效果

代码如下(示例):

       public class SemaphoreTest
    {

        public void TestStart() 
        {
        
            Console.WriteLine(" SemaphoreTest TestStart Start !");
            IntObj intObj = new IntObj();
      
            for (Int32 i = 0; i < 10; i++)
            {
            
                new TaskFactory().StartNew(() =>
                {
                    AddCount(intObj);
                    AddCount_EventLock(intObj);
                });
            }
            Console.WriteLine(" SemaphoreTest TestStart END !");
        }
        
        public void AddCount(IntObj intObj)
        {  

            intObj.num_Norml++;
            WriteLineThread(intObj);
            Thread.Sleep(500);
        }
        SemaphoreLock tLock = new SemaphoreLock(10);  
        public void AddCount_EventLock(IntObj intObj)
        {
            tLock.Enter();

            intObj.num_Lock++;
            WriteLineThread_EventLock(intObj);
            Thread.Sleep(500);

            tLock.Leave();
        }
        public void WriteLineThread(IntObj intObj )
        {
            Thread.Sleep(200);
            ConsoleColor currentForeColor = Console.ForegroundColor;
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine($"num_Norml :{ intObj.num_Norml},{Thread.CurrentThread.ManagedThreadId}");
            Console.ForegroundColor = currentForeColor;
            Thread.Sleep(200);
        }

        public void WriteLineThread_EventLock(IntObj intObj)
        {
            Thread.Sleep(200);
            ConsoleColor currentForeColor = Console.ForegroundColor;
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine($"num_Lock:{ intObj.num_Lock},{Thread.CurrentThread.ManagedThreadId}");
            Console.ForegroundColor = currentForeColor;
            Thread.Sleep(200);
        }

    }

效果如下
当信号量锁初始化的时候允许最大10个线程效果
在这里插入图片描述
当信号量锁初始化的时候允许最大1个线程效果
在这里插入图片描述
此时的结果就和AutoResetEvent事件锁一样的效果了


总结

可以看出,当最大线程数1的时候,信号量和AutoResetEvent事件效果一样。但是信号量的如果多次释放可能会出现SemaphoreFullException的异常。
当最大线程数大于1的时候,将可能有多个线程同时变量。那种情况使用呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值