实施关键部分

创建关键部分的方式更好,更快?

使用二进制信号量,在sem_wait和sem_post之间。
或者使用primefaces操作:

#include  void critical_code(){ static volatile bool lock = false; //Enter critical section while ( !__sync_bool_compare_and_swap (&lock, false, true ) ){ sched_yield(); } //... //Leave critical section lock = false; } 

无论使用何种方法,代码中性能最差的问题与您使用的锁类型无关,而是锁定代码而不是数据。

话虽如此,没有理由像你那样推出自己的自旋锁。 如果你想要一个自旋锁,可以使用pthread_spin_lock如果你想要一个可以在争用时屈服于其他进程的锁,可以使用pthread_mutex_locksem_wait (带有二进制信号量)。 您编写的代码是两个世界中使用sched_yield 最糟糕的 sched_yield 。 对sched_yield的调用将确保在存在锁争用和cpu负载的情况下,锁等待至少几毫秒(可能是整个调度时间片),并且当存在争用但没有cpu负载时它将烧掉100%cpu(例如,由于锁定器在IO中被阻挡。 如果你想获得自旋锁的任何好处,你需要在不进行任何系统调用的情况下进行旋转。 如果你想要产生cpu的任何好处,你应该使用一个正确的同步原语,它将使用(在Linux上) futex (或等效的)操作来准确地产生,直到锁可用 – 没有更短,不再。

如果一切都超过了你的头脑,甚至不要考虑写自己的锁..

如果对锁的争用很少和/或从未长时间保持,旋转锁的性能会更好。 否则你最好使用阻止而不是旋转的锁。 当然有混合锁可以旋转几次,如果无法获得锁,那么它们就会阻塞。

哪个更适合您取决于您​​的应用程序。 只有你可以回答那个问题。

你在gcc文档中看起来不够深入。 这种类型的锁的正确内置__sync_lock_test_and_set__sync_lock_test_and_set__sync_lock_release 。 这些完全可以保证您需要这样的东西。 就新的C11标准而言,这将是具有操作atomic_flag_test_and_setatomic_flag_clear

正如R.已经指出的那样,把sched_yield放入循环中,真是个坏主意。

如果临界区内的代码只是一些周期,那么它的执行落在调度切片边界上的概率很小。 将被阻止主动旋转的线程数最多为处理器数减1。 如果您在没有立即获得锁定时立即执行执行,则所有这些都不成立。 如果你对锁屈服有真正的争用,那么你将拥有大量的上下文切换,这将使你的系统几乎处于保持状态。

正如其他人所指出的那样,它并不是关于锁定代码有多快。 这是因为一旦使用“xchg reg,mem”启动锁定序列,锁定信号将通过高速缓存向下发送到所有总线上的设备。 当最后一个设备确认它将保持并确认时 – 这可能需要数百甚至数千个时钟周期才能执行实际交换。 如果您最慢的设备是经典的PCI卡,它的总线速度为33 MHz,约为CPU内部时钟的百分之一。 PCI设备(如果有效)需要几个时钟周期(@ 33 MHz)才能响应。 在此期间,CPU将等待确认返回。

大多数自旋锁可能用于设备驱动程序,其中例程不会被操作系统抢占,但可能会被更高级别的驱动程序中断。

关键部分实际上只是一个自旋锁,但与操作系统接口,因为它可能是先发制人的。