代码改变世界

自旋锁SPIN LOCK的编程实现

  心中无码  阅读(1572)  评论(3编辑  收藏  举报

自旋锁是一种轻量级的互斥量,以达到对共享资源的保护。下面结合代码进行说明。

     

复制代码
void
spin_enter(
int* crt
)
{
spin_try:
__asm
{
mov eax, crt
lock bts dword ptr [eax], 0
jz spin_wait
}

return;

__asm
{
spin_wait:
pause
mov eax, spin_var
test eax,
1
jne spin_wait
jmp spin_try
}
}
复制代码

  

      上面这段代码是关键。*crt初始值为0,lock bts dword ptr[eax], 0是将crt的第0位传递给ZF,同时将crt置为1。同时这条语句是被lock作为前缀的,即这条语句的执行无法并发。执行这条语句后,如果自旋锁此时是空闲的,那么ZF被置为0,反之,ZF被置为1。ZF被置为0时,直接return,否则jz spin_wait,进行wait操作,wait操作是监控crt的值,如果crt的值为1,说明自旋锁仍被占用,循环。否则说明自旋锁此时空闲,跳转到spin_try重新去获取资源。

     最后给出所有的代码,包括多线程的测试。

复制代码
#include <stdio.h>
#include
<windows.h>
#include
<process.h>
#include
<stddef.h>
#include
<stdlib.h>
#include
<conio.h>


int spin_var = 0;
int count = 0;

/*进入临界区*/
void
spin_enter(
int* crt
)
{
spin_try:
__asm
{
mov eax, crt
lock bts dword ptr [eax], 0
jz spin_wait
}

return;

__asm
{
spin_wait:
pause
mov eax, spin_var
test eax,
1
jne spin_wait
jmp spin_try
}
}

void
spin_leave(
int* crt
)
{
*crt = 0;
}

void thread_fun( void *ch)
{
int id = (int)ch;

while (1)
{
spin_enter(
&spin_var);
printf(
"Thread %d : %d\n", id, count++);

spin_leave(
&spin_var);
}

_endthread();
}


void
main(
void)
{
int thread_num = 10;
int i;

for (i = 0; i < thread_num; i++)
{
_beginthread(thread_fun,
0, (void *) (i));
}

while (1)
{
Sleep(
1000);
}
}
复制代码

  

1
 

PS.曾传说高铁追尾是调度程序的问题,哥菊花一紧,程序猿除了编码外,又多了一个替罪羊的功能,

     天朝V5,还好只是传说…

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示