-
-
[求助] 自实现自旋锁失败
-
发表于:
2017-12-20 18:55
3857
-
最近在看并发,并行的资料,想着实现一个自旋锁,结果出了一个摸不清头脑的结果.还请有这方面知识的大腿,帮看下`~`
#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
保证是并行原子,不应该这样.
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!