这取决于您的操作系统.我已经看到yield在内核中旋转,旋转,通用条件变量,用户空间控制的调度以及具有内核支持的专用锁定原语.
纺纱和纺纱yield具有可怕的性能.从理论上讲,用户控制的调度(参见调度程序激活)应该具有最佳性能,但据我所知,没有人能够在所有情况下都能正常工作.内核中的通用条件变量和具有内核支持的专用锁定原语应该与Linux中的futex或多或少相同,这是后者的最佳示例.
在某些情况下,纺纱可以有更好的性能.在Solaris中,内核中的某些锁定原语具有自适应模式,只要持有锁的进程在不同的cpu上运行,锁就会自动旋转.如果锁具所有者睡觉或被抢占,锁定服务员也会进入睡眠状态.在其他内核中,存在锁定类别,锁定所有者在锁定时不能被抢占或休眠,因此在这些情况下,旋转也很有效.总的来说,特别是在用户空间中,旋转具有如此可怕的退化情况(旋转过程旋转直到它被抢占以让锁拥有者运行)这对于性能非常糟糕.请注意,像这样的专用锁定原语futex可以实现这样的优化,这是通用条件变量通常不能实现的.
简而言之:是的,也许......
这是实现细节,如果至少不知道您正在谈论哪个操作系统,则很难说。通常,互斥体的解锁只会将等待线程标记为“可运行”,但不会(必然)在那时调用调度程序 - 即使调度程序被调用,也不意味着 T2 将是下一个线程跑步。
在Linux中,代码进入mutex_unlock()检查是否有任何等待任务(通过检查锁定计数是否小于零 - 它从1开始表示解锁,单个锁定请求将其设置为零,进一步尝试锁定会使其变为负值)。如果有进一步的等待过程,它会调用“慢速路径解锁”,它通过几个重定向函数来允许实现细节,最终会出现__mutex_unlock_common_slowpath- 再往下几行,有一个调用wake_up_process最终会出现try_to_wake_up-它本质上只是将任务排队为“准备运行”,然后调用调度程序(通过多层函数!)