首页 > 编程语言 >C# Semaphore

C# Semaphore

时间:2024-02-23 09:11:57浏览次数:30  
标签:C# section object critical threads semaphore Semaphore

https://dotnetpattern.com/threading-semaphore

C# semaphore allows only a limited number of threads to enter into a critical section. Semaphore is mainly used in scenarios where we have limited number of resources and we have to limit the number of threads that can use it.

How Semaphore Works

Semaphores are Int32 variables stored in a operating system resources. When we initialize the semaphore object we initialize with number. This number limits the threads that can enter into the critical section.

When a thread enters into a critical section, it decreases the Int32 variable with 1 and when a thread exits from a critical section, it increases the Int32 variable with 1.

When the Int32 variable is 0, no thread can enters into a critical section.

Below  is the syntax of C# semaphore initialization.

Semaphore semaphoreObject = new Semaphore(initialCount: 0, maximumCount: 5);

We initialize semaphore object with two parameters:

  1. InitialCount
  2. MaximumCount

Maximum count defines how many maximum threads can enter into a critical section. InitialCount set the value of Int32 variable. For example if we set the maximum count of 3 and initial count of 0. That means 3 threads are already in the critical section. If we set the maximum count of 3 and initial count of 3, that means maximum 3 threads can enter into a critical section and there is no threads currently in the critical section. 

Used semaphore between multiple processes

Alternatively semaphore has another constructor which takes additional string as parameter. This string parameter is a unique string which is used for using semaphore between multiple process.

Below is the syntax of creating semaphore.

Semaphore semaphoreObject = new Semaphore(initialCount: 0, maximumCount: 5, name: "MyUniqueNameApp");

WaitOne Method

Threads can enter into the critical section by using WaitOne method. They called the WaitOne method on semaphore object. If the Int32 variable maintained by semaphore is greater than 0 then it allows calling thread to enter.

Below is the syntax of calling WaitOne method.

semaphoreObject.WaitOne();

In another overload of semaphore WaitOne method, we can pass the time interval for which a thread can wait to get a signal from semaphore. If thread has not received signal within a time internal specified, It returns false value.

bool isSignalled = semaphoreObject.WaitOne(TimeSpan.FromSeconds(4));

In the above example, if calling thread does not receive signal within specified 4 seconds, then it returns false. If it receives signal it returns true.

Release Method

When a thread exits from the critical section, it must call the Release method to increment the counter maintained by semaphore object. It allows waiting threads to enter into a critical section.

semaphoreObject.Release();

By default Release method only increment the counter by 1. That means only one thread exits from the critical section. We can also pass a parameter to Release method to defines how many threads are actually exits.

semaphoreObject.Release(3);

In the above code, we pass 3 parameter to Release method. This will notify semaphore object that 3 threads are actually exits from the critical section. So semaphore object increment the counter by 3.

Semaphore Example

In the following example shows how to use semaphore object with Printer object. We have to limit the number of threads that can concurrently use Printer object. For that we use semaphore object with maximum count of 3. 

class Program
{
    static void Main(string[] args)
    {
        Semaphore semaphoreObject = new Semaphore(initialCount: 3, maximumCount: 3, name: "PrinterApp");
        Printer printerObject = new Printer();

        for (int i = 0; i < 20; ++i)
        {
            int j = i;
            Task.Factory.StartNew(() =>
                {
                    semaphoreObject.WaitOne();
                    printerObject.Print(j);
                    semaphoreObject.Release();
                });
        }
        Console.ReadLine();
    }
}

class Printer
{
    public void Print(int documentToPrint)
    {
        Console.WriteLine("Printing document: " + documentToPrint);
        //code to print document
        Thread.Sleep(TimeSpan.FromSeconds(5));
    }
}

We initialize semaphore object with 3 initialcount and maximum of 3 and gives unique name “PrinterApp”. We start the for loop with runs from 0 to 20. We started threads using the TaskFactory.

Each thread calls WaitOne method of semaphore object before using the Printer object. This will limit the number of number of threads using the Printer object. After using printer object each thread calls the Release method for increment the counter of semaphore. This allows further threads to enter into a critical section.

标签:C#,section,object,critical,threads,semaphore,Semaphore
From: https://www.cnblogs.com/chinasoft/p/18028588

相关文章

  • C++动态内存分配探秘:new与malloc的关键差异及实例解析
     概述:在C++中,new和malloc均用于动态内存分配,但存在关键差异。new是C++运算符,能调用构造函数,返回类型明确;而malloc是C函数,仅分配内存,需手动类型转换。示例源代码生动演示了它们在构造函数调用和类型信息方面的不同。在C++中,new 和 malloc 都用于动态内存分配,但它们之间......
  • C++强制类型转换详解:四种操作符解析与实例演示
     概述:C++中的强制类型转换是实现数据类型间转换的关键机制,包括static_cast、dynamic_cast、const_cast和reinterpret_cast四种。这些操作符适用于不同的场景,通过实例源代码详细阐述了它们的使用方法和步骤。在C++中,强制类型转换是将一个数据类型的值转换为另一个数据类型的过......
  • dremio cloner 简单试用
    以前简单介绍过dremiocloner工具,以下是一个简单试用dremio环境准备基于docker-compose,具体可以参考https://github.com/rongfengliang/dremio_cluster_docker-compose完成配置安装dremioclonerdremiocloner没有直接提供为一个pip包,需要自己安装clone代码......
  • C# CountdownEvent
    https://dotnetpattern.com/threading-countdownevent C#CountdownEventisasynchronizationprimitivewhichunblocksawaitingthreadwhenitsreceivessignalacertainnumberoftimes.CountdownEventisusedin fork-join scenarios.Asshownintheabove......
  • ABC341总结
    ABC341总结Score:1825Rank:737F其实按照题意,原图可能有环,但是因为转移有权值限定,转换一下就是DAG,进行拓扑排序。GAK所差最后一题,使用数形结合思想,x轴为数组下标,y轴为值域。题意是给出左端点,右端点任意,求区间平均值最大进行前缀和处理,然后会惊奇的发现,平均数转化成了两点间......
  • 使用nmcli命令配置网卡(NetworkManager)
    配置网络IP地址sudonmcliconnectionmodifyens3ipv6.methoddisabledsudonmcliconnectionmodifyens3ipv4.methodmanualipv4.address192.168.1.6/24ipv4.gateway192.168.1.1ipv4.dns192.168.1.1sudonmcliconnectiondownens3&&sudonmcliconnectio......
  • XSS-Cross Site Scripting
    一、XSS简介与危害简介跨站脚本攻击XSS(CrossSiteScripting),为了不和层叠样式表CSS(CascadingStyleSheets)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面插入恶意Script代码,当用户浏览该页面时,嵌入Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。......
  • Machine Learning - The Sigmoid Function
    CalculateNodeOutput.TaskYouaregiventhevaluesforw1,w2,b,x1andx2andyoumustcomputetheoutputforthenode.Usethesigmoidastheactivationfunction.InputFormatw1,w2,b,x1andx2ononelineseparatedbyspacesOutputFormatFloatrounded......
  • C++ 第四节课 C和C++指针的区别 C的宏函数和C++内联函数的优缺点
    #include<iostream>//定义一个宏函数#defineADD(x,y)x+y;//宏函数具有速度快等特点但是写代码有些业务比较繁琐,所以C++中使用了内联函数优化//在定义函数前面添加一个inline把这个函数变成内联函数inlineintmax(intx,inty){returnx>y?x:y;}usi......
  • Object— Object.defineProperty()(详解、原理、作用、使用场景、使用方式)
    一.Object.defineProperty()详解Object.defineProperty()是JavaScript中用于定义或修改对象的属性的方法,可以控制属性的特性(如可枚举性、可配置性、可写性等)。Object.defineProperty()方法的语法如下:Object.defineProperty(obj,prop,descriptor)obj:要在其上定义属性......