问题描述
什么方式更好更快地创造关键的部分?
通过二进制信号,sem_wait和sem_post之间。结果
或用原子操作:
的#include<&sched.h中GT;虚空critical_ code(){
静态挥发布尔锁= FALSE; //进入临界区
而(!__ sync_bool_compare_and_swap(安培;锁,假的,真正的)){
SCHED_YIELD();
} // ... //离开临界区
锁定= FALSE;
}
不管你用什么方法,你的code表现最差的问题已经无关什么类型你使用的锁定,但事实上,你锁定code,而不是数据。
随着中说,没有理由推出自己的自旋锁这样。要么使用 pthread_spin_lock
如果你想要一个自旋锁,否则的pthread_mutex_lock
或 sem_wait
(用二进制信号量),如果你想有一个锁争用时可以产生到其他进程。你写的code是在最严重的是如何使用 SCHED_YIELD
两全其美的。到 SCHED_YIELD
的通话将确保锁在那里有两个锁争用和CPU负载的情况下等待至少几毫秒(也可能是整个调度时间片),它会燃烧100%的CPU时,有争论,但没有CPU负载(由于锁定持有人被挡在IO,例如)。如果你想要得到任何的自旋锁的好处,你需要定纺未做任何系统调用。如果你想要的任何屈服CPU的好处,你应该是使用适当的同步原语将使用(在Linux上) futex的
(或同等学历)操作产生完全相同,直到锁可用 - 无短和不再
和如果碰巧所有参加在你的头上,甚至不考虑如何编写自己的锁。
What way is better and faster to create a critical section?
With a binary semaphore, between sem_wait and sem_post.
Or with atomic operations:
#include <sched.h>
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;
}
Regardless of what method you use, the worst performance problem with your code has nothing to do with what type of lock you use, but the fact that you're locking code rather than data.
With that said, there is no reason to roll your own spinlocks like that. Either use pthread_spin_lock
if you want a spinlock, or else pthread_mutex_lock
or sem_wait
(with a binary semaphore) if you want a lock that can yield to other processes when contended. The code you have written is the worst of both worlds in how it uses sched_yield
. The call to sched_yield
will ensure that the lock waits at least a few milliseconds (and probably a whole scheduling timeslice) in the case where there's both lock contention and cpu load, and it will burn 100% cpu when there's contention but no cpu load (due to the lock-holder being blocked in IO, for instance). If you want to get any of the benefits of a spin lock, you need to be spinning without making any syscalls. If you want any of the benefits of yielding the cpu, you should be using a proper synchronization primitive which will use (on Linux) futex
(or equivalent) operations to yield exactly until the lock is available - no shorter and no longer.
And if by chance all that went over your head, don't even think about writing your own locks..
这篇关于实施关键部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!