0
행동이 중요 섹션을 좋아하는 재귀 잠금을 작성합니다. 하지만 재귀 기능을 구현할 때 문제가 있습니다. 같은 코드 :Windows에서 이벤트 및 인터록 프리미티브로만 재귀 잠금을 구현하는 방법은 무엇입니까?
#include "own_cs.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <assert.h>
#include <malloc.h>
#include <stdlib.h>
#include <stdio.h>
struct own_critical_section
{
long own_lock_count; // count of locked thread, -1 means unlock , other means lock.
HANDLE own_event; // auto-reset
DWORD own_owning_thread_id; // owner thread of lock
};
void InitialOwnCriticalSection(own_critical_section** own_cs)
{
*own_cs = (own_critical_section*)malloc(sizeof(own_critical_section));
(*own_cs)->own_lock_count = -1;
(*own_cs)->own_event = CreateEventW(NULL, FALSE, FALSE, NULL);
(*own_cs)->own_owning_thread_id = 0;
}
void DeleteOwnCriticalSection(own_critical_section* own_cs)
{
assert(own_cs != NULL);
CloseHandle(own_cs->own_event);
free(own_cs);
}
void EnterOwnCriticalSection(own_critical_section* own_cs)
{
for (int spin_count = 0; spin_count < 500; ++ spin_count)
{//spinlock
if (-1L == InterlockedCompareExchange(&own_cs->own_lock_count, -1L, -1L))
break;
Sleep(0);
}
if(0 < InterlockedIncrement(&own_cs->own_lock_count) &&
(own_cs->own_owning_thread_id != ::GetCurrentThreadId()))
//there is no guarantee that own_owning_thread_id is set before comparison with tid.so this comparison is not thread-safe.
{
//locked
WaitForSingleObject(own_cs->own_event, INFINITE);
}
own_cs->own_owning_thread_id = ::GetCurrentThreadId();
}
void LeaveOwnCriticalSection(own_critical_section* own_cs)
{
if(-1L != InterlockedDecrement(&own_cs->own_lock_count) &&
(::GetCurrentThreadId() == own_cs->own_owning_thread_id))
{
SetEvent(own_cs->own_event);
}
}
문제는 EnterOwnCriticalSection 루틴은,이 함수에서 주석으로,이 비교는 스레드로부터 안전하지 않습니다 tid.so과 비교하기 전에 설정 own_owning_thread_id 보장은 없습니다.
"C++", 예, 완전히보고 있습니다. – Puppy
@DeadMG 범위 지정 연산자가 있으므로 apparantly입니까? (@OP : C++ 기능을 사용해야하고 C 태그를 제거해야합니다. 일반적으로 C 및 C++은 일반적으로 두 가지 언어입니다.) – moooeeeep
원하는 것을 수행하는 것처럼 보이는 CRITICAL_SECTION을 사용하지 않는 이유는 무엇입니까? – Ben