Semaphore [ /ˈseməfɔːr/ ]
信号量:主要作为进程之间以及同一进程的不同线程之间的同步和互斥手段。
可以把多线程比作马路,Semaphore比作红绿灯
比如马路有10车道,initialCount表示初次可通行数量,maximumCount最大可通行数量,比如设置为4,一次最多放4条,

主要方法
WaitOne()阻塞线程,等灯来
Release(N) 同时放行条数,最大不能超过maximumCount
Close()释放所有
使用方式1
有10个线程,同时只执行3条线程,每完成一个就Release一个,等待中的就补上去
using System;
using System.Threading;
namespace TestThread
{
class Program
{
// A semaphore that simulates a limited resource pool.
//
private static Semaphore _pool;
// A padding interval to make the output more orderly.
//private static int _padding;
public static void Main()
{
// Create a semaphore that can satisfy up to three
// concurrent requests. Use an initial count of zero,
// so that the entire semaphore count is initially
// owned by the main program thread.
//
_pool = new Semaphore(3, 3);
// Create and start five numbered threads.
//
for (int i = 1; i <= 10; i++)
{
Thread t = new Thread(new ParameterizedThreadStart(Worker));
t.Name = "线程" + i;
// Start the thread, passing the number.
//
t.Start(i);
}
Console.WriteLine("Main thread exits.");
}
private static void Worker(object num)
{
// Each worker thread begins by requesting the
// semaphore.
Console.WriteLine(Thread.CurrentThread.Name + "等待中...");
_pool.WaitOne();
// A padding interval to make the output more orderly.
//int padding = Interlocked.Add(ref _padding, 100);
Console.WriteLine(Thread.CurrentThread.Name + ">>>>>>>>>>>>>>>>>>开始执行..." + Environment.TickCount64);
// The thread's "work" consists of sleeping for
// about a second. Each thread "works" a little
// longer, just to make the output more orderly.
//
Thread.Sleep(1000 + (int)num * 100);
Console.WriteLine(Thread.CurrentThread.Name + "<<<<<<<<<<<<<<<<<退出" + Environment.TickCount64);
;
Console.WriteLine("Semaphore.Release---------------------" + _pool.Release());
}
}
}
线程9等待中...
Main thread exits.
线程1等待中...
线程2等待中...
线程3等待中...
线程4等待中...
线程5等待中...
线程6等待中...
线程7等待中...
线程8等待中...
线程10等待中...
线程9>>>>>>>>>>>>>>>>>>开始执行...1268589031
线程1>>>>>>>>>>>>>>>>>>开始执行...1268589031
线程2>>>>>>>>>>>>>>>>>>开始执行...1268589031
线程1<<<<<<<<<<<<<<<<<退出1268590140
Semaphore.Release---------------------0
线程3>>>>>>>>>>>>>>>>>>开始执行...1268590140
线程2<<<<<<<<<<<<<<<<<退出1268590234
Semaphore.Release---------------------0
线程4>>>>>>>>>>>>>>>>>>开始执行...1268590234
线程9<<<<<<<<<<<<<<<<<退出1268590937
Semaphore.Release---------------------0
线程5>>>>>>>>>>>>>>>>>>开始执行...1268590937
线程3<<<<<<<<<<<<<<<<<退出1268591437
Semaphore.Release---------------------0
线程6>>>>>>>>>>>>>>>>>>开始执行...1268591437
线程4<<<<<<<<<<<<<<<<<退出1268591640
Semaphore.Release---------------------0
线程7>>>>>>>>>>>>>>>>>>开始执行...1268591640
线程5<<<<<<<<<<<<<<<<<退出1268592437
Semaphore.Release---------------------0
线程8>>>>>>>>>>>>>>>>>>开始执行...1268592437
线程6<<<<<<<<<<<<<<<<<退出1268593031
Semaphore.Release---------------------0
线程10>>>>>>>>>>>>>>>>>>开始执行...1268593031
线程7<<<<<<<<<<<<<<<<<退出1268593343
Semaphore.Release---------------------0
线程8<<<<<<<<<<<<<<<<<退出1268594234
Semaphore.Release---------------------1
线程10<<<<<<<<<<<<<<<<<退出1268595046
Semaphore.Release---------------------2
使用方式2
using System;
using System.Collections.Generic;
using System.Threading;
namespace TestThread
{
class Program2
{
private static Semaphore _semaphore;
private static Queue<int> m_TaskQueue = new Queue<int>();
public static void Main()
{
//
_semaphore = new Semaphore(0, int.MaxValue);
ThreadPool.QueueUserWorkItem(Run);
ThreadPool.QueueUserWorkItem(QueueTask);
Thread.Sleep(11000);
Console.WriteLine("Main thread exits.");
}
private static void QueueTask(object state)
{
for (int i = 0; i < 10; i++)
{
lock (m_TaskQueue)
{
m_TaskQueue.Enqueue(i);
_semaphore.Release();
}
Thread.Sleep(1000);
}
}
private static void Run(object state)
{
while (true)
{
Console.WriteLine("开始等待");
_semaphore.WaitOne();
int task = 0;
lock (m_TaskQueue)
{
if (m_TaskQueue.Count == 0)
{
_semaphore.Dispose();
Console.WriteLine("队列执行结束");
return;
}
task = m_TaskQueue.Dequeue();
}
Console.WriteLine("执行任务" + task);
}
}
}
}
网友评论