• 深入理解.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);
            }
    
        }     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    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);
            }
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

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


    总结

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

  • 相关阅读:
    Redis架构之哨兵机制与集群
    es6新增-map数据结构
    线段树、树状数组模板(复制粘贴确实好用)
    day17正则表达式作业
    C++ 类和对象
    深度神经网络——贝叶斯与朴素贝叶斯定理
    X-ray Photoelectron Spectroscopy (XPS)——* 化学位移
    6个国内外高质量icon素材网站分享给你,实用不花钱!
    使用Python实现微信群发每日一句
    SpringBoot bbs(3~4) 过度创作总结。
  • 原文地址:https://blog.csdn.net/l1158513573/article/details/125453570