首页
社区
课程
招聘
[求助] 自实现自旋锁失败
发表于: 2017-12-20 18:55 3884

[求助] 自实现自旋锁失败

2017-12-20 18:55
3884
 

最近在看并发,并行的资料,想着实现一个自旋锁,结果出了一个摸不清头脑的结果.还请有这方面知识的大腿,帮看下`~`

#include "stdafx.h"
#include <windows.h>

typedef struct _SPIN_LOCK
{
    DWORD dwLocked{};    // 是否锁上
}SPINLOCK, *PSPINLOCK;

int g_i{};            // 全局计数变量
SPINLOCK g_SL;        // 全局自旋锁

bool IsLocked(SPINLOCK* pSL);        // 返回值等于true,表示锁上;否,没有锁上
void SpinLock(SPINLOCK* pSL);        // 锁住
void SpinUnlock(SPINLOCK* pSL);        // 解锁

DWORD (WINAPI ThreadProc)(LPVOID lpThreadParameter);

int main()
{
    HANDLE hThread[2]{};
    hThread[0] = CreateThread(0, 0, &ThreadProc, 0, 0, 0);
    hThread[1] = CreateThread(0, 0, &ThreadProc, 0, 0, 0);
    WaitForMultipleObjects(2, hThread, 1, INFINITE);

    printf("%d\n", g_i);

    system("pause");

    return 0;
}

bool IsLocked(SPINLOCK* pSL)
{
    __asm {
        push esi;
        push edi;

        mov edi, pSL;

        mov esi, 1;
        mov eax, 0;
        cmpxchg [edi], esi;    // cmpxchg是原子操作,但不能保互斥执行`~`

        pop edi;
        pop esi;
    }
}

void SpinLock(SPINLOCK* pSL) { while (IsLocked(pSL)); }

void SpinUnlock(SPINLOCK* pSL) { pSL->dwLocked = 0; }

DWORD WINAPI ThreadProc(LPVOID lpThreadParameter)
{
    int i = 1000000;
    while (i--) {
        SpinLock(&g_SL);
        g_i++;
        SpinUnlock(&g_SL);
    }

    return 0;
}

调试的结果是SpinUnlock(&g_SL);有一次没有成功,还有这样的操作.百思不得姐`~`
如果cmpxchg保证是并行原子,不应该这样.


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 1080
活跃值: (180)
能力值: (RANK:30 )
在线值:
发帖
回帖
粉丝
2
在  cmpxchg  加一个  LOCK  指令?
2017-12-20 22:30
0
雪    币: 1
活跃值: (394)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3

所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切[1] 换到另一个线程)。

 

这个是SMP的问题.用lock保证lock cmpxchg dword ptr [edi],esi的独占`~`谢谢大佬!

2017-12-21 08:13
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
4
使用Windows提供的ExInter系列函数不就可以实现自旋锁了么?而且Windows也是这样实现的啊!
2017-12-24 11:49
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
5
而且ExInter系列函数,系统能保证互斥执行,为什么不用?非要自己汇编实现?
2017-12-24 11:52
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
6
楼主,我看你的题目对我胃口,我就花了点时间,实现了一个自旋锁,开了200个线程来测试,可以通过,楼主,要不要我上传代码?
2017-12-25 21:06
0
雪    币: 1
活跃值: (394)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
谢谢!学会了高级回复好像可附件.网坏了几天
2017-12-26 20:49
0
雪    币: 1
活跃值: (394)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
czcqq 楼主,我看你的题目对我胃口,我就花了点时间,实现了一个自旋锁,开了200个线程来测试,可以通过,楼主,要不要我上传代码?
谢谢!学会了高级回复好像可附件.网坏了几天
2017-12-26 20:50
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
9
JChiron 谢谢!学会了高级回复好像可附件.网坏了几天
现在在上班,等我回去,就上传代码
2017-12-30 09:49
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
10
czcqq 现在在上班,等我回去,就上传代码
源码
上传的附件:
2017-12-30 19:33
0
游客
登录 | 注册 方可回帖
返回
//