关键部分与计算信号量有什么关系? [英] What does a critical section have to do with counting semaphores?
本文介绍了关键部分与计算信号量有什么关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
Some people说您应该使用互斥锁来保护共享资源(即临界区),而信号量应该用于发送信号,反之亦然。因此,据我所知,信号量与临界区无关。
然而,包括Wikipedia在内的许多其他文章都指出信号量是用来解决临界区问题的。说二进制信号量解决临界区问题是否更正确,因为它们基本上充当互斥锁,而计算信号量则是另一回事,不属于"资源保护器"类别?
推荐答案
计数信号量可用于资源保护,但它们用于不同资源的方式通常与互斥信号量不同。
一个典型的例子是队列。对于动态调整大小的队列,您有一个计数信号量来跟踪队列中当前有多少项。消费者等待该信号量,告诉他们何时可以从队列中读取项目。
对于固定大小的队列,添加第二个计数信号量,跟踪队列中的空闲空间量。编写者等待它,以确定何时允许他们将项目推送到队列。
您确实经常将互斥信号量与这些信号量结合使用,以确保在任何给定时间只有一个线程修改队列本身。
例如,以下是使用Win32计数的信号量(和互斥体)的固定大小队列的一些代码:
#ifndef QUEUE_H_INCLUDED
#define QUEUE_H_INCLUDED
#include <windows.h>
template<class T, unsigned max = 256>
class queue {
HANDLE space_avail; // at least one slot empty
HANDLE data_avail; // at least one slot full
CRITICAL_SECTION mutex; // protect buffer, in_pos, out_pos
T buffer[max];
long in_pos, out_pos;
public:
queue() : in_pos(0), out_pos(0) {
space_avail = CreateSemaphore(NULL, max, max, NULL);
data_avail = CreateSemaphore(NULL, 0, max, NULL);
InitializeCriticalSection(&mutex);
}
void push(T data) {
WaitForSingleObject(space_avail, INFINITE);
EnterCriticalSection(&mutex);
buffer[in_pos] = data;
in_pos = (in_pos + 1) % max;
LeaveCriticalSection(&mutex);
ReleaseSemaphore(data_avail, 1, NULL);
}
T pop() {
WaitForSingleObject(data_avail,INFINITE);
EnterCriticalSection(&mutex);
T retval = buffer[out_pos];
out_pos = (out_pos + 1) % max;
LeaveCriticalSection(&mutex);
ReleaseSemaphore(space_avail, 1, NULL);
return retval;
}
~queue() {
DeleteCriticalSection(&mutex);
CloseHandle(data_avail);
CloseHandle(space_avail);
}
};
#endif
这篇关于关键部分与计算信号量有什么关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文