广州市外贸网站建设企业,做环保网站案例,seo优化培训机构,南城区仿做网站自旋锁以其高效闻名。顾名思义#xff0c;自旋即如果无法成功锁住锁资源则会一直循环尝试锁#xff0c;这与互斥锁的行为较为不同#xff08;互斥锁如果无法锁住则会挂起等待#xff09;。但其特性也决定了其使用场景#xff0c;对于简单几步即可完成对共享资源操作的场景…自旋锁以其高效闻名。顾名思义自旋即如果无法成功锁住锁资源则会一直循环尝试锁这与互斥锁的行为较为不同互斥锁如果无法锁住则会挂起等待。但其特性也决定了其使用场景对于简单几步即可完成对共享资源操作的场景自旋锁效率将会高于互斥量。
本文给出自旋锁的一种x86平台实现。
其实gcc在4.1以后的版本就支持了内置的自旋锁实现而各大类UNIX系统中也提供了pthread_spin_lock这样的自旋锁函数。那么为什么还要自己实现呢
这是由于一些历史遗留问题和跨平台移植共同导致的结果例如RHEL5 32位系统其自带的gcc并不支持自旋锁也没有pthread_spin_lock但我们依旧需要使用自旋锁特性那么只好自己动手丰衣足食了。
闲话少叙代码奉上
#define barrier() asm volatile (: : :memory)
#define cpu_relax() asm volatile (pause\n: : :memory)
static inline unsigned long xchg(void *ptr, unsigned long x)
{__asm__ __volatile__(xchg %0, %1:r (x):m (*(volatile long *)ptr), 0(x):memory);return x;
}void spin_lock(void *lock)
{unsigned long *l (unsigned long *)lock;while (1) {if (!xchg(l, 1)) return;while (*l) cpu_relax();}
}void spin_unlock(void *lock)
{unsigned long *l (unsigned long *)lock;barrier();*l 0;
}int spin_trylock(void *lock)
{return !xchg(lock, 1);
}可以看到这里我们使用了内联汇编且用到了汇编指令pause。
关于pause给出pause指令的一段解释 Improves the performance of spin-wait loops. When executing a “spin-wait loop,” a Pentium 4 or Intel Xeon processor suffers a severe performance penalty when exiting the loop because it detects a possible memory order violation. The PAUSE instruction provides a hint to the processor that the code sequence is a spin-wait loop. The processor uses this hint to avoid the memory order violation in most situations, which greatly improves processor performance. For this reason, it is recommended that a PAUSE instruction be placed in all spin-wait loops. 大意是说这个指令可以提升自旋等待的性能这个指令将作为对处理器的一个线索或者暗示hint让处理器尽量避免该指令出现时可能存在的内存乱序存储问题。
同时这个指令也将降低自旋等待时的电力消耗。pause指令是Pentium 4处理器引入的。 上面的例子中我们还使用了volatile关键字这个关键字在网上有非常多的文章详细解释主要是两方面作用
告诉编译器该关键字部分不可以做任何优化使用该关键字的变量每次必须从内存中读取而不能放在cache或寄存器中备份 感谢阅读