【发布时间】:2016-09-20 10:32:27
【问题描述】:
void
sema_down (struct semaphore *sema)
{
old_level = intr_disable ();
while (sema->value == 0)
{
list_push_back (&sema->waiters, &thread_current ()->elem);
thread_block ();
}
sema->value--;
intr_set_level (old_level);
}
上面这段代码是 PintOS 中的一个机械锁互斥锁。 PintOS 针对单处理器系统。因此,仅禁用中断就足够了。对方不可能使用互斥锁。
那么,让我们考虑一个多处理器设计:
void
sema_down (struct semaphore *sema)
{
old_level = intr_disable ();
while (!lock cmpxchg(1,0)) // it is just pseudocode-idea
{
list_push_back (&sema->waiters, &thread_current ()->elem);
thread_block ();
}
intr_set_level (old_level);
}
old_level = intr_disable ();。它关闭了中断,但仅在该 CPU 的上下文中至关重要。
它可以是 MP 架构中获取互斥锁的函数的原型。但是,list_push_back 有问题。它也必须是安全的多线程。但是,我们不能使用互斥锁使其安全,因为我们现在才实现它!
主要问题是: 两个(或更多)CPU 是否有可能在 Ring 0 级别(内核)上执行代码?
并且,依赖于第一个答案的子问题:
如果不是,则没有我上面描述的问题。但是-它如何实现?
如果是(这似乎不可能或很难实现),我的上述考虑呢(这只是潜在问题的示例)。 我们必须使用
spinlocks或lock-free structures吗?
【问题讨论】:
-
你能把帖子简化为一个明确的问题吗?如果自旋锁和无锁编程用于同步对非常短的关键部分(例如更新列表的关键部分)的访问并且无法避免 AFAIK,那么它们也不错。
-
@MargaretBloom,我进行了编辑以更清楚地说明我的要求。基本上,它是单一问题的帖子。我没有摆脱我的子问题,因为它们依赖于上下文,没有必要将它们放在其他帖子中。 ( 我认同)。希望对你更友好。
-
我对此特别困惑:“两个(或更多)CPU 是否有可能在 Ring 3 级别(内核)上执行代码”。为什么你会惊讶于不同的 CPU 可以执行相同的代码?以及为什么在Ring 3(即用户模式)旁边有一个kernel?
-
@MargaretBloom,CPU 可以执行相同的代码并不奇怪。很明显——他们可以。我考虑他们是否可以同时在 Ring 0(我编辑了我的帖子,我之前犯了一个错误)级别上执行代码。
-
由于 IOAPIC 可以跨多个内核分配外部中断,这将要求每个处理器能够同时操作环 0 中的代码。处理器上的 ring 3 程序可能会请求进行系统调用,从而可能将运行它的处理器切换到 ring 0。这可以在所有内核上完成。所以是的,有可能同时在多个内核上的 ring 0 处运行代码。如果您有一个仅使用单核的多核系统(启动时默认),则没有问题。您必须在使用之前启用/引导每个核心。
标签: multithreading x86 operating-system