>是不是只能等 A 执行完毕 不是的。即使 A 线程占用了 CPU,那也不意味着你能一直占着直到你的任务结束。 有因素会打算 A,然后切换到 B 。比如分给 A 任务的时间消耗完了,A 被调度出去; 比如中断和抢占打断了。
另外,不要用户态使用自旋锁,非常非常地愚蠢,除非你真的清楚自己在做什么。 引用 Linus 的话: >I repeat: do not use spinlocks in user space, unless you actually know what you're doing. And be aware that the likelihood that you know what you are doing is basically nil.
至于锁和核心的问题,锁主要用在进线程的同步互斥直接,和核心的关系不是很大,由于线程可以再用户态或者核心态实现,如果在用户态实现,哪怕是单核心的 u,照样宏观上使用自选锁啥的也没有问题。因为线程间抢占的是资源,是资源的竞争而不是 cpu 时间片。比如说,线程 a 在使用 s 资源,这时线程 b 也请求 s 资源,假设是单核心,现在 u 分给了 a,a 使用一段时间,但是时间片到了轮给 b,不过 a 还没有释放 s 资源,到 b 后由于请求的资源 s 没有被释放,那么 b 就一直轮询,也就是执行循环的指令。当然由于是单核心的,s 不可能被释放,所以 b 就只能一直到时间片结束,又到 a,直到 a 释放 s 资源。可以说 b 忙等待了个寂寞。
从上面也可以看出来,为什么在用户态要少用自选锁,当然如果用的信号量或者互斥锁啥的,是睡眠等待机制,那么轮到 b 后,发现 s 资源没有被释放,所以 b 调用 block 原语,阻塞掉自己陷入睡眠态,u 又轮到 a,直到 a 释放 s 资源后调用 wake 原语唤醒 b 。