2015년 8월 31일 월요일

윈도우/리눅스 공통 뮤텍스/쓰레드/이벤트/세마포어 라이브러리

< Mutex.h >
 #ifndef __MUTEX_H__  
 #define __MUTEX_H__  
   
 #ifdef WIN32  
 #include <windows.h>  
 #include <process.h>  
   
 #define MUTEX     HANDLE  
 #define PTHREAD_MUTEX_INITIALIZER     CreateMutex(NULL, FALSE, NULL)  
 #else  
 #include <pthread.h>  
   
 #define MUTEX     pthread_mutex_t  
 #endif  
   
 int MUTEX_INIT(MUTEX *mutex);  
 int MUTEX_LOCK(MUTEX *mutex);  
 int MUTEX_UNLOCK(MUTEX *mutex);  
 int MUTEX_DESTROY(MUTEX *mutex);  
   
 #endif  
   

< Mutex.cpp >
 #include "Mutex.h"  
   
 int MUTEX_INIT(MUTEX *mutex)  
 {  
 #ifdef WIN32  
      *mutex = CreateMutex(NULL, FALSE, NULL);  
      return *mutex == NULL ? -1 : 0;  
 #else  
      pthread_mutexattr_t attr;  
      pthread_mutexattr_init(&attr);  
      pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);  
      return pthread_mutex_init(mutex, &attr);  
 #endif  
 }  
   
 int MUTEX_DESTROY(MUTEX *mutex)  
 {  
 #ifdef WIN32  
      if (*mutex) {  
           CloseHandle(*mutex);  
           *mutex = NULL;  
      }  
      return 0;  
 #else  
      return pthread_mutex_destroy(mutex);  
 #endif  
 }  
   
 int MUTEX_LOCK(MUTEX *mutex)  
 {  
 #ifdef WIN32  
      return WaitForSingleObject(*mutex, INFINITE) == WAIT_FAILED ? -1 : 0;  
 #else  
      return pthread_mutex_lock(mutex);  
 #endif  
 }  
   
 int MUTEX_UNLOCK(MUTEX *mutex)  
 {  
 #ifdef WIN32  
      return ReleaseMutex(*mutex) == 0 ? -1 : 1;  
 #else  
      return pthread_mutex_unlock(mutex);  
 #endif  
 }  
   

< Mutex 사용 >
 MUTEX mutex;  
 ...  
 MUTEX_INIT(&mutex);  
 ...  
 MUTEX_LOCK(&mutex);  
 ...  
 MUTEX_UNLOCK(&mutex);  
 ...  
 MUTEX_DESTROY(&mutex);  
 static MUTEX static_mutex = PTHREAD_MUTEX_INITIALIZER;  
 ...  
 MUTEX_LOCK(&static_mutex );  
 ...  
 MUTEX_UNLOCK(&static_mutex );  
 ...  

< Thread.h >
 #ifndef __THREAD_H__  
 #define __THREAD_H__  
   
 #ifdef WIN32  
 #include <windows.h>  
 #include <process.h>  
   
 #define THREAD          HANDLE  
 #define THREAD_FUNC     unsigned __stdcall  
 #else  
 #include <pthread.h>  
   
 #define THREAD          pthread_t  
 #define THREAD_FUNC     void*  
 #endif  
   
 int THREAD_CREATE(THREAD *thread, THREAD_FUNC func(void *), void *param);  
 int THREAD_JOIN(THREAD *thread);  
 void THREAD_DESTROY(THREAD *thread);  
   
 #endif  
   

< Thread.cpp >

 #include "Thread.h"  
   
 int THREAD_CREATE(THREAD *thread, THREAD_FUNC func(void *), void *param)  
 {  
 #ifdef WIN32  
      *thread = (HANDLE)_beginthreadex(NULL, 0, func, param, 0, NULL);  
      return *thread == NULL ? -1 : 0;  
 #else  
      return pthread_create(thread, NULL, func, param);  
 #endif  
 }  
   
 int THREAD_JOIN(THREAD *thread)  
 {  
 #ifdef WIN32  
      return WaitForSingleObject(*thread, INFINITE) == WAIT_FAILED ? -1 : 0;  
 #else  
      int status;  
      return pthread_join(*thread, (void **)&status);  
 #endif  
 }  
   
 void THREAD_DESTROY(THREAD *thread)  
 {  
 #ifdef WIN32  
      if (*thread)  
           CloseHandle(*thread);  
 #endif  
      *thread = NULL;  
 }  
   

< Thread 사용 >
 THREAD thread;  
 ...  
 static THREAD_FUNC ThreadFunc(void* lpParam) {  
 ...  
   return 0;  
 }  
   
 THREAD_CREATE(&thread, ThreadFunc, this);  
 ...  
 THREAD_JOIN(&thread);  
 THREAD_DESTROY(&thread);  
   

< Event.h>
 #ifndef __EVENT_H__  
 #define __EVENT_H__  
   
 #ifdef WIN32  
 #include <windows.h>  
 #define     EVENT     HANDLE  
 #else  
 #include <pthread.h>  
   
 typedef struct {  
   pthread_mutex_t mutex;  
   pthread_cond_t cond;  
   bool triggered;  
 } mrevent;  
   
 #define EVENT     mrevent  
 #endif  
   
 void EVENT_INIT(EVENT *event);  
 void EVENT_DESTROY(EVENT *event);  
 void EVENT_WAIT(EVENT *event);  
 void EVENT_SET(EVENT *event);  
 void EVENT_RESET(EVENT *event);  
   
 #endif  
   

< Event.cpp>
 #include "Event.h"  
   
 void EVENT_INIT(EVENT *event)  
 {  
 #ifdef WIN32  
      *event = CreateEvent(NULL, TRUE, FALSE, NULL);  
 #else  
      pthread_mutex_init(&event->mutex, 0);  
      pthread_cond_init(&event->cond, 0);  
      event->triggered = false;  
 #endif  
 }  
   
 void EVENT_DESTROY(EVENT *event)  
 {  
 #ifdef WIN32  
      CloseHandle(*event);  
 #else  
      pthread_mutex_destroy(&event->mutex);  
      pthread_cond_destroy(&event->cond);  
 #endif  
 }  
   
 void EVENT_WAIT(EVENT *event)  
 {  
 #ifdef WIN32  
      WaitForSingleObject(*event, INFINITE);  
 #else  
      pthread_mutex_lock(&event->mutex);  
      while (!event->triggered)  
           pthread_cond_wait(&event->cond, &event->mutex);  
      pthread_mutex_unlock(&event->mutex);  
 #endif  
 }  
   
 void EVENT_SET(EVENT *event)  
 {  
 #ifdef WIN32  
      SetEvent(*event);  
 #else  
   pthread_mutex_lock(&event->mutex);  
   event->triggered = true;  
   pthread_cond_signal(&event->cond);  
   pthread_mutex_unlock(&event->mutex);  
 #endif  
 }  
   
 void EVENT_RESET(EVENT *event)  
 {  
 #ifdef WIN32  
      ResetEvent(*event);  
 #else  
      pthread_mutex_lock(&event->mutex);  
      event->triggered = false;  
      pthread_mutex_unlock(&event->mutex);  
 #endif  
 }  
   

< Event 사용 >
 EVENT event;  
 ...  
 EVENT_INIT(&event);  
 ...  
 EVENT_SET(&event);  
 ...  
 EVENT_RESET(&event);  
 ...  
 EVENT_WAIT(&event);  
 ...  
 EVENT_DESTROY(&event);  

< MySemaphore.h >
 #ifndef __MY_SEMAPHORE_H__  
 #define __MY_SEMAPHORE_H__  
   
 #ifdef WIN32  
 #include <windows.h>  
 #define SEMAPHORE     HANDLE  
 #else  
 #include <semaphore.h>  
 #define SEMAPHORE     sem_t  
 #endif  
   
 int SEM_INIT(SEMAPHORE *sem, int init, int max);  
 int SEM_WAIT(SEMAPHORE *sem);  
 int SEM_POST(SEMAPHORE *sem);  
 int SEM_DESTROY(SEMAPHORE *sem);  
   
 #endif  
   

< MySemaphore.cpp >
 #include "MySemaphore.h"  
   
 int SEM_INIT(SEMAPHORE *sem, int init, int max)  
 {  
 #ifdef WIN32  
      *sem = CreateSemaphore(NULL, init, max, NULL);  
      return *sem == NULL ? -1 : 0;  
 #else  
      return sem_init(sem, 0, init);  
 #endif  
 }  
   
 int SEM_DESTROY(SEMAPHORE *sem)  
 {  
 #ifdef WIN32  
      if (*sem) {  
           CloseHandle(*sem);  
           *sem = NULL;  
      }  
      return 0;  
 #else  
      return sem_destroy(sem);  
 #endif  
 }  
   
 int SEM_WAIT(SEMAPHORE *sem)  
 {  
 #ifdef WIN32  
      return WaitForSingleObject(*sem, INFINITE);  
 #else  
      return sem_wait(sem);  
 #endif  
 }  
   
 int SEM_POST(SEMAPHORE *sem)  
 {  
 #ifdef WIN32  
      return ReleaseSemaphore(*sem, 1, NULL) == TRUE ? 0 : -1;  
 #else  
      return sem_post(sem);  
 #endif  
 }  
   

< MySemaphore 사용 >
 SEMAPHORE sem;  
 ...  
 SEM_INIT(&sem, 0, 10);  
 ...  
 SEM_WAIT(&sem);  
 ...  
 SEM_POST(&sem);  
 ...  
 SEM_DESTROY(&sem);  

댓글 없음:

댓글 쓰기