posted by Kyleslab 2010. 12. 10. 22:07

-----Thread.h
#pragma once

#include <functional>

//Rari? 리소스를 얻으면 바로 초기화한다.보통 윈도 api를 사용한다. 독립적으로 되려면 매기기 마다 컴파일해야한다. ios로 가면 ios api를 써야한다.

class Thread
{
public:
 Thread( std::function< void () > const & threadFunc );//스레드를 만들 함수를 넘기다. 리턴타입없고 인자도없다.
 ~Thread();

public:
 unsigned int
  getThreadId() const;
 unsigned int
  getThreadHandle() const;

private:
 Thread( Thread const & value ){}
 Thread & operator=( Thread const & value){ return *this;}

private:
 unsigned int _threadId;
 unsigned int _threadHandle;
 std::function< void () > _threadFunc; // 터지는 것을 방지 하고 위해서 쓰레드의 생명주기를 클래스와 같게 한다.

};

---Thread.cpp
//#ifdef _WIN32 //플랫폼 독립적인 녀석을 만들때

#include "stdafx.h"

#include "Thread.h"

#include <Windows.h>
#include <process.h>

static unsigned int __stdcall ThreadEntryPoint ( void * arg ) // static외부에서 절대 접근불가함수 이파일안에서만 동작 윈도우 스레드로 만들어져서 넘길수있다.
{
 (* ( std::function< void () >* )( arg ))();

 return 0;

}


Thread::Thread( std::function< void () > const & threadFunc )
 :_threadFunc( threadFunc )
{
 //우리가 만들고 싶은 것은 threadFunc 스레드인데 비긴스레드는 불가능 하다. 스레드엔트리포인트는 비긴스레드가 가능하니까 스레드펀크함수를 변수로 해서 전달한다.
 _threadHandle = ::_beginthreadex( NULL, 
      0,
      ThreadEntryPoint,
      ( void *)( &_threadFunc ), // 없어진것을 호출하면 터진다.
      0,
      &_threadId);
}

Thread::~Thread()
{
 ::WaitForSingleObject( ( HANDLE )( _threadHandle ), INFINITE); //반드시해주어야함 모든 자식 스레드를 종료해주기 위해 메인스레드가 종료하면 소멸자를 호출하게 되고 자신의 핸들스레드가 종료될때까지 기다리게 한다.!!!
 ::CloseHandle( ( HANDLE )( _threadHandle ) ); // 그다음에 메인 스레드를 종료한다.
}

unsigned int
 Thread::getThreadId() const
{
 return _threadId;
}

unsigned int
 Thread::getThreadHandle() const
{
 return _threadHandle;
}

---SpinLock.h
#pragma once

#include <Windows.h>
class SpinLock
{
public:
 SpinLock();
 ~SpinLock();

public:
 void lock();
 void unlock();

private:
 SpinLock(SpinLock const & value){}
 SpinLock &operator = (SpinLock const & rhs){return * this;}

private:
 ::CRITICAL_SECTION _lock;
};

-- SpinLock.cpp
#include "stdafx.h"

#include "SpinLock.h"

SpinLock::SpinLock()
{
 ::InitializeCriticalSection(&_lock); //객체 생성
}

SpinLock::~SpinLock()
{
 ::DeleteCriticalSection(&_lock); //해제
}

void SpinLock::lock()
{
 ::EnterCriticalSection(&_lock);
}

void SpinLock::unlock()
{
 ::LeaveCriticalSection(&_lock);
}

--Mutex.h
#pragma once

#include <Windows.h>
class MutexLock
{
public:
 MutexLock();
 ~MutexLock();

public:
 void lock();
 void unlock();

private:
 MutexLock(MutexLock const & value){}
 MutexLock &operator = (MutexLock const & rhs){return * this;}

private:
 HANDLE _lock;
};

--Mutex.cpp
#include "stdafx.h"

#include "MutexLock.h"

MutexLock::MutexLock()
{
  _lock = ::CreateMutexA(NULL, FALSE, NULL);//객체 생성
}

MutexLock::~MutexLock()
{
  ::CloseHandle(_lock); //해제
}

void MutexLock::lock()
{
 ::WaitForSingleObject(_lock, INFINITE);
}

void MutexLock::unlock()
{
 ::ReleaseMutex(_lock);
}

'Operations Dev > Concurrency' 카테고리의 다른 글

자체 뮤텍스락 이용  (0) 2010.12.10
자체 스핀락 이용  (0) 2010.12.10