通过这个示例信号量实现(对于SMP系统),我理解多处理器原子检查需要测试和设置。但是,一旦我们添加原子检查,禁用中断是不是多余的?无论如何,禁用中断仅在一个处理器上提供原子性。除了信号量队列之外,还需要加以保护。
class semaphore {
private int t;
private int count;
private queue q;
public semaphore(int init)
{
t = 0;
count = init;
q = new queue();
}
public void P()
{
Disable interrupts;
while (TAS(t) != 0) { /* just spin */ };
if (count > 0) {
count--;
t = 0;
Enable interrupts;
return;
}
Add process to q;
t = 0;
Enable interrupts;
Redispatch;
}
public V()
{
Disable interrupts;
while (TAS(t) != 0) { /* just spin */ };
if (q == empty) {
count++;
} else {
Remove first process from q;
Wake it up;
}
t = 0;
Enable interrupts;
}
}
答案 0 :(得分:9)
虽然确实在一个处理器上关闭中断不足以保证多处理器系统中的原子内存访问(因为,正如您所提到的,其他处理器上的线程仍然可以访问共享资源),我们关闭部分中断多处理器信号量实现,因为我们不想在进行测试和设置时进行计划。
如果一个持有测试和集合的线程被取消调度,那么没有其他线程可以对信号量做任何事情(因为它的计数受到该测试和设置的保护)线程在它睡着时正在使用(这不是好)。为了保证不会发生这种情况,我们会在使用测试和设置时关闭处理器上的中断。