我正在尝试了解如何在使用线程时使用信号量。
我有 2 个使用相同资源的线程 - ArrayList
。
一种方法向列表中添加一个随机温度,另一种方法计算列表的平均温度。
如何在此上下文中使用信号量的方法 Wait
和 Release
?
以及如何控制计算平均温度的线程在将某些内容添加到我的列表后启动。
这是我的一些代码:
class Temperature
{
private static Random random = new Random();
private static ArrayList buffer = new ArrayList();
static SemaphoreSlim e, b;
public static void Main (string[] args)
{
e = new SemaphoreSlim(6); //how will this work?
b = new SemaphoreSlim(1);
Thread t1 = new Thread (Add);
t1.Start ();
Thread t2 = new Thread (Average);
t2.Start ();
}
public static void Add()
{
int temperature;
for (int i=0; i<50; i++)
{
temperature = random.Next (36, 42);
Console.WriteLine ("Temperature added to buffer: " + temperature);
b.Wait ();
e.Wait ();
buffer.Add(temperature);
b.Release ();
Thread.Sleep (50);
}
}
}
最佳答案
正如其他人所指出的,在这里直接锁比信号量更合适。
这是因为您只有一个资源(buffer
)要防止并发访问。只有一个资源要么忙,要么不忙,锁是最合适的。
信号量在资源容量有限时很有用。一个例子:
酒吧或夜总会等有防火限制的场所。人们(线程)等待,直到保镖(信号量)看到 field (资源)有容量。第一批客户不必等待很长时间,事实上,他们会立即获准入住。
当他们进入保镖(信号量)时,点击他的计数器来记录消耗了多少容量。一旦 field 达到容量,就会排起长队 - 人们将不得不等待,直到有人离开。
随着人们离开(他们释放)和保镖(信号量)减少他的计数器 - 现在相应数量的人可以进入。
因此 - 您在信号量上设置容量,资源的消费者等待可用(如果容量不可用,它们将阻塞),消费者释放他们已经完成了资源。
一个共同的特征(但不是必需的)是当您不知道(或不关心)资源的哪个特定部分正在被消耗时,信号量经常被使用,只是它的一些可用部分正在被使用.
信号量与互斥量
Mutex
类似于lock
,但它是一个命名的系统级资源。 Mutex
必须由获取它的 Thread
释放,而 Semaphore
没有线程标识。这可以解释为什么您有时会看到优先使用计数为 1 的 Semaphore
而不是 Mutex
。
关于c# - 使用信号量进行线程编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19764501/