이 코드는 작동하지만 InterlockedIncrement 함수를 올바르게 사용 했습니까? m_count의 올바른 메모리 정렬이 가장 중요한 문제입니다. 우리가 x86-64 시스템에 있고 64 비트 응용 프로그램을 컴파일한다고 가정합니다 (중요한 경우). 그건 그렇고, 내 실제 목적을 위해 나는 m_count를 휘발성 long으로 선언 할 수 없으며, InterlockedIncrement (& m_count)를 사용한다. 그러나 힙의 데이터에 대한 포인터 여야합니다.InterlockedIncrement 함수에 대해 올바른 메모리 정렬로 힙에서 할당하는 방법은 무엇입니까?
#include <Windows.h>
#include <malloc.h>
class ThreadSafeCounter {
public:
ThreadSafeCounter()
{
// Are those arguments for size and alignment correct?
void* placement = _aligned_malloc(sizeof(long), sizeof(long));
m_count = new (placement) long(0);
}
~ThreadSafeCounter()
{
_aligned_free(const_cast<long*>(m_count));
}
void AddOne()
{
InterlockedIncrement(m_count);
}
long GetCount()
{
return *m_count;
}
private:
volatile long* m_count;
};
왜 힙에 있어야합니까? _aligned_malloc을 사용하고 싶습니까? 어쨌든 _aligned_malloc은 컴파일러 확장입니다. 따라서 정렬 요구 사항을 충족 할 수있는 GCC 및 MSVC 컴파일러에서 사용할 수있는 #pragma pack 지시문을 사용할 수도 있습니다. 그리고 GCC와 MSVC의 기본 프라 그마 패킹은 인터 로킹 된 작업의 기본 정렬 요구 사항을 이미 충족시킵니다. 그래서 당신은 정말로이 문제에 대해 과도하게 생각한 것 같습니다. –
이 ThreadSafeCounter 클래스는 간단한 예입니다. 내가 실제로하고있는 일은 std :: shared_ptr와 같은 것이지만, 몇 가지 추가 기능이 있습니다. 그리고 그 때문에 힙에 카운터가 있어야합니다. – zeroes00
카운터가 힙에있을 수 있지만 그것을 수행하는 방법을 할당 할 필요가 없으며 std :: shared_ptr과 같은 클래스의 경우 클래스에서 인라인 될 수 있고 정렬로 장식 될 수 있으므로 _align_malloc이 수행됩니다) a) 성능을 떨어 뜨리고 b) 자물쇠가없는 환경에서 문제를 일으킬 수있는 자체 자물쇠 섹션에 붙이십시오. – Necrolis