System2008. 11. 25. 15:35


세마포어는 뮤텍스에서 확장된 개념인데, 쉽게 설명하면...
뮤텍스에 접근가능한 쓰레드의 최대개수를 설정할 수 있습니다.

그 밖에 또 다른 차이점 한가지는 뮤텍스는 자신을 생성한 프로세스에 종속적이나,
세마포어는 프로세스에 자유롭게 호출할 수 있습니다.
-> 이 부분은 다음 포스팅에 쉽게 설명하겠습니다.

1. lpSemaphoreAttributes
지겹게 등장하는 커널 오브젝트 핸들에 대한 보안 속성이져.

2. lInitialCount
세마포어의 초기 개수를 설정합니다

3. lMaximumCount
세마포어가 가질 수 있는 최대 개수를 설정합니다.
보통 IInitialCount 와 같거나 큰 값을 넣습니다.

4. lpName
세마포어에 이름을 지정합니다.
다음 포스팅에 설명할 부분인데, 이렇게 이름을 지정하면
서로다른 프로세스 사이에도 이 세마포어에 접근할 수 있습니다.


세파포어 카운트가 10이라면 최대 10개의 쓰레드가 임계영역에 접근할 수 있게됩니다.
세마포어 획득은 WaitForSingleObject 를 사용하고, 반환은 ReleaseSemaphore 를 사용합니다.

아래는 세마포어를 아용한 명동교자라는 예제 ;;;
 
  1. /*  
  2.     MyongDongKyoJa.cpp  
  3.     프로그램 설명: 카운트 세마포어에 대한 이해  
  4.     시뮬레이션 제한 요소:  
  5.         1. 테이블이 총 10개이고, 동시에 총 10분의 손님만 받을 수 있다고 가정한다.  
  6.         2. 오늘 점심시간에 식사하러 오실 예상되는 손님의 수는 총 50분이다.  
  7.         3. 각 손님들께서 식사 하시는 시간은 대략 10분에서 30분 사이이다.  
  8. */ 
  9.  
  10.  
  11. #include <stdio.h>  
  12. #include <stdlib.h>  
  13. #include <time.h>  
  14. #include <windows.h>  
  15. #include <process.h>  
  16. #include <tchar.h>  
  17.  
  18. #define NUM_OF_CUSTOMER 50  
  19. #define RANGE_MIN 10  
  20. #define RANGE_MAX (30 - RANGE_MIN)  
  21. #define TABLE_CNT 10  
  22.  
  23.  
  24. HANDLE hSemaphore;  
  25. DWORD randTimeArr[50];  
  26.  
  27. void TakeMeal(DWORD time)  
  28. {  
  29.     WaitForSingleObject(hSemaphore, INFINITE);  
  30.     _tprintf( _T("Enter Customer %d~ \n"), GetCurrentThreadId());  
  31.  
  32.     _tprintf(_T("Customer %d having launch~ \n"), GetCurrentThreadId());  
  33.     Sleep(1000 * time); // 식사중인 상태를 시뮬레이션 하는 함수.  
  34.  
  35.     ReleaseSemaphore(hSemaphore, 1, NULL);  
  36.     _tprintf( _T("Out Customer %d~ \n\n"), GetCurrentThreadId());  
  37. }  
  38.  
  39.  
  40. unsigned int WINAPI ThreadProc( LPVOID lpParam )   
  41. {   
  42.     TakeMeal((DWORD)lpParam);  
  43.     return 0;  
  44. }  
  45.  
  46.  
  47. int _tmain(int argc, TCHAR* argv[])  
  48. {  
  49.     DWORD dwThreadIDs[NUM_OF_CUSTOMER];  
  50.     HANDLE hThreads[NUM_OF_CUSTOMER];  
  51.      
  52.     srand( (unsigned)time( NULL ) );    // random function seed 설정  
  53.  
  54.  
  55.     // 쓰레드에게 전달할 random 값 총 50개 생성.  
  56.     for(int i=0; i<NUM_OF_CUSTOMER ;i++)  
  57.     {  
  58.         randTimeArr[i] = (DWORD) (  
  59.                 ((double)rand() / (double)RAND_MAX) * RANGE_MAX + RANGE_MIN  
  60.             );  
  61.     }  
  62.  
  63.     // 세마포어 생성.  
  64.     hSemaphore = CreateSemaphore (  
  65.                    NULL,    // 디폴트 보안관리자.  
  66.                    TABLE_CNT,      // 세마포어 초기 값.  
  67.                    TABLE_CNT,      // 세마포어 최대 값.  
  68.                    NULL     // unnamed 세마포어 구성.  
  69.                  );  
  70.     if (hSemaphore == NULL)   
  71.     {  
  72.         _tprintf(_T("CreateSemaphore error: %d\n"), GetLastError());  
  73.     }  
  74.  
  75.  
  76.     // Customer를 의미하는 쓰레드 생성.  
  77.     for(int i=0; i<NUM_OF_CUSTOMER; i++)  
  78.     {  
  79.         hThreads[i] = (HANDLE)  
  80.             _beginthreadex (   
  81.                 NULL,  
  82.                 0,                        
  83.                 ThreadProc,                 
  84.                 (void*)randTimeArr[i],                      
  85.                 CREATE_SUSPENDED,            
  86.                 (unsigned *)&dwThreadIDs[i]     
  87.             );  
  88.  
  89.         if(hThreads[i] == NULL)  
  90.         {  
  91.             _tprintf(_T("Thread creation fault! \n"));  
  92.             return -1;  
  93.         }  
  94.     }  
  95.  
  96.     for(int i=0; i<NUM_OF_CUSTOMER; i++)  
  97.     {  
  98.         ResumeThread(hThreads[i]);  
  99.     }  
  100.  
  101.     WaitForMultipleObjects(NUM_OF_CUSTOMER, hThreads, TRUE, INFINITE);  
  102.  
  103.     _tprintf(_T("----END-----------\n"));  
  104.  
  105.     for(int i=0; i<NUM_OF_CUSTOMER; i++)  
  106.     {  
  107.         CloseHandle(hThreads[i]);  
  108.     }  
  109.       
  110.     CloseHandle(hSemaphore);  
  111.  
  112.     return 0;  
  113. }  
Posted by skensita