首页
论坛
课程
招聘
[求助] 自实现自旋锁失败
2017-12-20 18:55 2385

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

2017-12-20 18:55
2385
 

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

#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保证是并行原子,不应该这样.


看雪招聘平台创建简历并且简历完整度达到90%及以上可获得500看雪币~

收藏
点赞0
打赏
分享
最新回复 (9)
雪    币: 1079
活跃值: 活跃值 (80)
能力值: (RANK:30 )
在线值:
发帖
回帖
粉丝
axiuno 活跃值 2017-12-20 22:30
2
0
在  cmpxchg  加一个  LOCK  指令?
雪    币:
活跃值: 活跃值 (179)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
spobit 活跃值 2017-12-21 08:13
3
0

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

 

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

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