Semaphore, sometimes called a Semaphore, is a facility used in multithreaded environments to ensure that two or more critical pieces of code are not called concurrently. Before entering a critical code segment, the thread must acquire a semaphore; Once that critical piece of code is complete, the thread must release the semaphore. Other threads that want to enter the critical code segment must wait until the first thread releases the semaphore. To do this, create a Semaphore VI and place Acquire Semaphore VI and Release Semaphore VI at the beginning and end of each key snippet. Verify that these semaphores VI refer to the semaphore originally created.
public static class SemaphoreSample
{
// The initial semaphore is 0 and the maximum number is 3
private static readonly Semaphore Sema = new Semaphore(0.3);
public static void DoWork()
{
while (true)
{
// Decrease by 1 semaphore
// If the semaphore is 0, wait
Sema.WaitOne();
Console.WriteLine("Do Work"); }}public static void Run()
{
for (var i = 0; i < 5; i++)
{
var thread = new Thread(DoWork);
thread.Start();
}
// while (true)
/ / {
// // adds 3 semaphores
// Sema.Release(3);
// Thread.Sleep(1000);
// }}}Copy the code
Mix lock and semaphore implementation to produce consumer model
public static class ProducerSample
{
private static readonly Queue<int> Queue = new Queue<int> ();private static readonly object Lock = new object(a);private static readonly SemaphoreSlim Sema = new SemaphoreSlim(0.int.MaxValue);
public static void Consumer()
{
while (true)
{
Sema.Wait();
lock (Lock)
{
Console.WriteLine($"Data={Queue.Dequeue()},ThreadId={Thread.CurrentThread.ManagedThreadId},Count={Queue.Count}"); }}}public static void Producer()
{
var job = 0;
while (true)
{
lock (Lock)
{
Queue.Enqueue(job++);
}
Sema.Release(1);
Thread.Sleep(100); }}public static void Run()
{
for (var i = 0; i < 5; i++)
{
var consumer = newThread(Consumer); consumer.Start(); } Producer(); }}Copy the code
Semaphore – free edition realizes the production consumer model
public static class MonitorProducerSample
{
private static readonly Queue<int> Queue = new Queue<int> ();private static readonly object Lock = new object(a);public static void Consumer()
{
while (true)
{
lock (Lock)
{
while (Queue.Count == 0)
{
// Add the current thread to the wait queue and release the lock
// Threads wait to wake up uniformly
Monitor.Wait(Lock);
// After waking up, the thread retrieves the lock and continues executing the code
}
Console.WriteLine($"Data={Queue.Dequeue()},ThreadId={Thread.CurrentThread.ManagedThreadId},Count={Queue.Count}"); }}}public static void Producer()
{
var job = 0;
while (true)
{
lock (Lock)
{
Queue.Enqueue(job++);
// The thread that wakes up the lock waits for one consuming thread in the column
Monitor.Pulse(Lock);
}
Thread.Sleep(100); }}public static void Run()
{
for (var i = 0; i < 5; i++)
{
var consumer = newThread(Consumer); consumer.Start(); } Producer(); }}Copy the code