SUBJECT:   semaphore¶õ ? 

Description :

o ¼¼¸¶Æ÷¾î (semaphore)¶õ (1) ?
  - µ¿±âÈ­ÀÇ ÀϹÝÀûÀÎ ¹æ¹ýÀÎ ¼¼¸¶Æ÷¾î ¹æ¹ýÀº ¼¼¸¶Æ÷¾î¶ó´Â Á¤¼ö º¯¼ö 
   (integer variable), ÇÁ·Î¼¼½º ´ë±â¿­(process waiting queue), 
    P¿Í VÀÇ µÎ ¸í·ÉÀ¸·Î ±¸¼ºµÈ´Ù. Ãʱ⠻óÅÂÀÇ º¯¼ö°ªÀº ÀÚ¿øÀÇ ¼ö¿Í °°À¸¸ç
    ´ë±â¿­Àº ºñ¾î ÀÖ´Ù. P¸í·ÉÀº º¯¼öÀÇ °ªÀ» Çϳª ÁÙÀÎ ÈÄ, 
    º¯¼öÀÇ °ªÀÌ 0º¸´Ù ÀÛÀ¸¸é ÇÁ·Î¼¼½º¸¦ ´ë±â¿­·Î Áý¾î ³Ö´Â´Ù. 
    ¹Ý´ë·Î 0º¸´Ù Å©¸é ±× ÇÁ·Î¼¼½º´Â °è¼Ó ÁøÇàµÈ´Ù. 
    V¸í·ÉÀº º¯¼öÀÇ °ªÀ» Çϳª Áõ°¡½ÃŲ´Ù.  ±× °á°ú°¡ 0º¸´Ù Å©¸é ÇÁ·Î¼¼½º´Â 
    °è¼ÓµÇ¸ç 0º¸´Ù ÀÛÀ¸¸é ´ë±â¿­ÀÇ ÇÁ·Î¼¼½º Çϳª¸¦ Áغñ »óÅ·Π¸¸µé°í, 
    ÇÁ·Î¼¼½ºÀÇ ¼öÇàÀº °è¼ÓµÈ´Ù.  °á±¹ º¯¼öÀÇ °ªÀº À½¼öÀÏ °æ¿ì´Â ´ë±â ÁßÀÎ 
    ÇÁ·Î¼¼½ºÀÇ ¼ö¸¦ ³ªÅ¸³»¸ç, ¾ç¼öÀÌ¸é »ç¿ë °¡´ÉÇÑ ÀÚ¿øÀÇ ¼ö¸¦ °¡¸®Å²´Ù.  
    À§¿¡¼­ µ¿±âÈ­¶õ ÇÁ·Î¼¼½ºÀÇ ½ÇÇàÀ» ½Ã°£¿¡ µû¶ó ¼ø¼­ÀûÀ¸·Î ó¸®ÇÏ´Â °ÍÀ» 
    µ¿±âÈ­¶ó ÇÑ´Ù.

o ¼¼¸¶Æ÷¾î (semaphore)¶õ (2) ?
  - ´ÙÀͽºÆ®¶ó(E.J.Dijkstra)°¡ Á¦¾ÈÇÑ µ¿½Ã¿¡ Á¤º¸¸¦ °øÀ¯ÇÏ¿© ¼öÇàµÇ´Â 
    µÎ °³ ÀÌ»óÀÇ ÇÁ·Î±×·¥À̳ª ÇÁ·Î¼¼½º¿¡¼­ È°µ¿(activity)ÀÇ À§Ä¡(coordination)¸¦
    ¼³Á¤ÇØ ÁÖ´Â µ¥ »ç¿ëµÇ´Â µ¿±âÈ­¸¦ À§ÇÑ ±âº» Á¶ÀÛ. ÀÌ´Â µÎ°³ ÀÌ»óÀÇ 
    ÇÁ·Î¼¼½º¿¡ ÀÇÇØ °øÀ¯µÇ´Â °íÀ¯º¯¼ö·Î Á¤ÀǵǴµ¥, º¸ÅëÀÇ ¹æ¹ýÀ¸·Î´Â 
    ´Ù·ê ¼ö ¾ø°í Ç×»ó P¿Í V¶ó´Â ¿¬»êÀ» ÅëÇؼ­¸¸ ¾×¼¼½ºÇÒ ¼ö ÀÖ´Ù.  
    ¼¼¸¶Æ÷¾î semÀ̶õ ´ÙÀ½°ú °°Àº ¿¬»êÀÌ Çã¿ëµÈ Á¤¼öÇü º¯¼ö¸¦ ¸»ÇÑ´Ù. 
   (P¿Í V¶õ À̸§Àº wait¿Í signalÀ̶õ ¸»ÀÇ ³×´ú¶õµå¾î¿¡¼­ ³ª¿Â°ÍÀ¸·Î 
    À̶§ signalÀ̶õ ¹°·Ð UNIXÀÇ signalÈ£Ãâ°ú´Â ´Ù¸£´Ù.) 
    µÎ ¿¬»êÀº ¸ðµÎ ¿øÀÚÈ­µÇ¾î¾ß ÇÑ´Ù. Áï semÀ» º¯°æÇÒ¼ö ÀÖ´Â ÇÁ·Î¼¼½º´Â 
    ÇÑ ¼ø°£¿¡ ¿ÀÁ÷ Çϳª »ÓÀÌ´Ù. 

    ------------------------------------------------------------------------------------------------
    | ÄÄÇ»ÅÍ°¡ ¿©·¯ ÇÁ·Î±×·¥À» µ¿½Ã¿¡ ¼öÇàÇÏ´Â ´ÙÁß ÇÁ·Î±×·¡¹Ö ½Ã½ºÅÛ¿¡¼­´Â ÇÁ·Î¼¼½ºµé°£ÀÇ »óÈ£    |
    | ¹èÁ¦¿Í µ¿±âÈ­¸¦ À§ÇÑ ±âº»ÀûÀÎ ¿¬»êÀÌ ÇÊ¿äÇÏ´Ù. ¼¼¸¶Æ÷¾î´Â ´ÙÀͽºÆ®¶ó°¡ Á¦¾ÈÇÑ ÇÁ·Î¼¼½º       |
    | µ¿±âÈ­¸¦ À§ÇÑ ±¸Á¶·Î, ÀÌ´Â ¿©·¯ ÇÁ·Î¼¼½ºµé¿¡ ÀÇÇØ °øÀ¯µÇ´Â º¯¼ö·Î Á¤ÀǵȴÙ.                  |
    | ±×·±µ¥ ÀÌ º¯¼ö´Â º¸ÅëÀÇ ¹æ¹ýÀ¸·Î´Â ¾×¼¼½ºÇÒ ¼ö ¾ø°í ¿ÀÁ÷ P¿Í V¶ó´Â ¿¬»êÀ¸·Î¸¸ ´Ù·ê ¼ö ÀÖ´Ù.  |
    | P¿Í V¿¬»êÀÇ Á¤ÀÇ´Â ´ÙÀ½°ú °°´Ù.                                                              |
    |                                                                                              |
    |              procedure P(S)   --> ÃÖÃÊ S°ªÀº 1ÀÓ                                             |
    |                  while S=0 do wait  --> S°¡ 0¸é 1ÀÌ µÉ¶§±îÁö ±â´Ù·Á¾ß ÇÔ                     |
    |                  S := S-1   --> S¸¦ 0·Î ¸¸µé¾î ´Ù¸¥ ÇÁ·Î¼¼½º°¡ µé¾î ¿ÀÁö ¸øÇϵµ·Ï ÇÔ         |
    |              end P                                                                           |
    |                                                                                              |
    |              procedure V(S) --> ÇöÀç»óÅ´ S°¡ 0ÀÓ                                           |
    |                  S := S+1   --> S¸¦ 1·Î ¿øÀ§Ä¡½ÃÄÑ ÇØÁ¦ÇÏ´Â °úÁ¤. ÀÌÁ¦´Â ´Ù¸¥ ÇÁ·Î¼¼½º°¡     |
    |              end V              µé¾î ¿Ã¼ö ÀÖÀ½                                               |
    |                                                                                              |
    | P¿Í V´Â ÂÉ°¶¼ö ¾ø´Â ´ÜÀÏ ¿¬»êÀÌ´Ù.                                                           |
    | Áï ÇÑ ÇÁ·Î¼¼½º°¡ P³ª V¸¦ ¼öÇàÇÏ°í ÀÖ´Â µ¿¾È¿¡´Â ÇÁ·Î¼¼½º°¡ ÀÎÅÍ·´Æ®¸¦ ´çÇÏÁö ¾Ê´Â´Ù.         |
    | ÀÌÁ¦ P¿Í V¸¦ »ç¿ëÇÏ¸é ´ÙÀ½°ú °°ÀÌ À§ÇèÁö¿ª(cirtical section)¿¡ ´ëÇÑ »óÈ£¹èÁ¦¸¦ ±¸ÇöÇÒ¼ö ÀÖ´Ù.|  
    |                                                                                              |
    |              P(S);                                                                           |
    |              -----------------                                                               |
    |              | À§ Çè Áö ¿ª   |                                                               |
    |              -----------------                                                               |
    |              V(S);                                                                           |
    |                                                                                              |
    | ÃÖÃÊ¿¡ SÀÇ °ªÀº 1ÀÌ´Ù. À§¿Í °°Àº À§ÇèÁö¿ªÀ» Æ÷ÇÔÇÏ´Â µÎ°³ÀÇ ÇÁ·Î¼¼½º A¿Í B°¡ ÀÖ´Ù°í ÇÏÀÚ.    |
    | A¿Í B´Â ¼­·Î µ¶¸³ÀûÀ¸·Î ¼öÇàµÇÁö¸¸, µÎ ÇÁ·Î¼¼½º°¡ µ¿½Ã¿¡ À§Çè Áö¿ªÀ¸·Î µé¾î°¡¼­´Â ¾ÈµÈ´Ù.    |
    | À§¿Í °°ÀÌ ¼¼¸¶Æ÷¾î¸¦ »ç¿ëÇϸé P(S)¸¦ ¸ÕÀú ¼öÇàÇÏ´Â ÇÁ·Î¼¼½º°¡ S¸¦ 0À¸·Î Çسõ°í À§ÇèÁö¿ª¿¡    |
    | µé¾î°¡¹Ç·Î ³ªÁß¿¡ µµÂøÇÏ´Â ÇÁ·Î¼¼½º´Â P¿¡¼­ ´õÀÌ»ó ÁøÇàµÇÁö ¸øÇÏ°í ±â´Ù¸®°Ô µÈ´Ù.            |
    | ¸ÕÀú µé¾î°¬´ø ÇÁ·Î¼¼½º°¡ V(S)¸¦ ÇØÁÖ¾î¾ß ºñ·Î¼­ P(S)¿¡¼­ ±â´Ù¸®´ø ÇÁ·Î¼¼½º°¡ À§ÇèÁö¿ª¿¡      |
    | µé¾î°¥ ¼ö ÀÖ°í µû¶ó¼­ »óÈ£¹èÁ¦°¡  ½ÇÇöµÈ´Ù.                                                  |
    | À§ÀÇ ¿¹´Â ÀÌÁø ¼¼¸¶Æ÷¾î (binary semaphore)·Î, ´ÜÁö ÇϳªÀÇ ÇÁ·Î¼¼½º¸¸ÀÌ À§ÇèÁö¿ª¿¡ µé¾î°¥ ¼ö  |
    | ÀÖµµ·Ï ÇÑ´Ù. ÇÑÆí SÀÇ ÃʱⰪÀ» NÀ¸·Î Çϸé ÃÖ´ë N°³ÀÇ ÇÁ·Î¼¼½º°¡ P(S)¸¦ Åë°úÇÒ ¼ö ÀÖ°Ô        |
    | µÇ´Âµ¥ ÀÌ·¯ÇÑ °æ¿ì¿¡´Â °è¼ö ¼¼¸¶Æ÷¾î (counting semaphore)¶ó Çϸç ÀÚ¿ø ÇÒ´ç¿¡ »ç¿ëÇÑ´Ù.       |
    ------------------------------------------------------------------------------------------------ 

    UNIX ½Ã½ºÅÛ V¿¡¼­ ±¸ÇöµÈ ¼¼¸¶Æ÷¾î´Â ÀÌ·¯ÇÑ °³³ä¿¡ ±âÃÊÇßÁö¸¸ º¸´Ù 
    ÀϹÝÀûÀÎ(±×¸®°í ¾Æ¸¶µµ º¸´Ù º¹ÀâÇÑ)±â´ÉÀ» Á¦°øÇÑ´Ù. 
    ¿ì¼± semget°ú semctlÀ» »ìÆ캸ÀÚ.
    <»ç¿ë¹ý>
         #include 
         #include 
         #include 
    
         key_t key;
         int sem_id, nsems, permflags, command;
         int retval, sem_num;
         union semun {
               int val;
               struct semid_ds *stat;
               ushort *array;
               } ctl_arg;
                .
                .
                .
         sem_id = semget(key, nsems, perflags);
         retval = semctl(sem_id, sem_num, command, ctl_arg);

     semget È£ÃâÀº msgget(get message queue)°ú À¯»çÇÏ´Ù. Àμö nsems´Â 
     ¼¼¸¶Æ÷¾î ÁýÇÕ¿¡ ÇÊ¿äÇÑ ¼¼¸¶Æ÷¾îÀÇ °¹¼ö¸¦ ³ªÅ¸³½´Ù. 
     µû¶ó¼­ UNIX ¼¼¸¶Æ÷¾î ¿¬»êÀº ¼¼¸¶Æ÷¾î Çϳª¸¸ÀÌ ¾Æ´Ï¶ó ÇÑ ÁýÇÕ Àüü¸¦
     ´Ù·ç°Ô µÈ´Ù. ÀÌ·Î ÀÎÇؼ­ ³ª¸ÓÁö ¼¼¸¶Æ÷¾î ·çƾ¿¡ ´ëÇÑ ÀÎÅÍÆäÀ̽º°¡ 
     º¹ÀâÇØÁø´Ù.
     semgetÈ£ÃâÀÌ ¼º°øÇÏ¸é ¼¼¸¶Æ÷¾î ÁýÇÕ ½Äº°ÀÚ¶ó´Â ¸Þ½ÃÁö Å¥ ½Äº°ÀÚ¿Í À¯»çÇÑ 
     ¿ªÇÒÀ» ÇÏ´Â °ÍÀÌ µ¹¾Æ¿Â´Ù. C ¾ð¾îÀÇ °ü½ÀÀ» µû¶ó¼­ ¼¼¸¶Æ÷¾î ÁýÇÕ¿¡ ´ëÇÑ 
     ÷ÀÚ´Â 0ºÎÅÍ nsems-1±îÁö ÀÖÀ» ¼ö ÀÖ´Ù.
     ÁýÇÕ ³»ÀÇ °¢ ¼¼¸¶Æ÷¾î´Â ´ÙÀ½°ú °°Àº °ªµéÀ» °®°Ô µÈ´Ù.
       . semval : ¼¼¸¶Æ÷¾îÀÇ °ªÀ¸·Î¼­ Ç×»ó ¾ç¼ö°¡ ÁöÁ¤µÈ´Ù. 
                  ¿©±â¿¡ °ªÀ» »õ·Î ÁöÁ¤ÇÏ·Á¸é ¹Ýµå½Ã ¼¼¸¶Æ÷¾î ½Ã½ºÅÛ È£ÃâÀ» 
                  ÅëÇؾßÇϸç ÇÁ·Î±×·¥¿¡¼­ ÀÏ¹Ý ÀÚ·áÇüÀÇ º¯¼ö¿Í °°ÀÌ Á÷Á¢
                  Á¢±Ù ÇÒ ¼ö´Â ¾ø´Ù.
       . sempid : ¼¼¸¶Æ÷¾î¿¡ Á¢±ÙÇß´ø ÃÖ±ÙÀÇ ÇÁ·Î¼¼½ºÀÇ ÇÁ·Î¼¼½º ½Äº°¹øÈ£ÀÌ´Ù.
       . semncnt : ¼¼¸¶Æ÷¾îÀÇ °ªÀÌ ÇöÀ纸´Ù Áõ°¡Çϱ⸦ ±â´Ù¸®´Â ÇÁ·Î¼¼½ºÀÇ °¹¼ö
       . semzcnt : ¼¼¸¶Æ÷¾îÀÇ °ªÀÌ 0À¸·Î µÇ±â±îÁö ±â´Ù¸®´Â ÇÁ·Î¼¼½ºÀÇ °¹¼ö
     Á¤ÀÇ¿¡¼­ ¾Ë ¼ö ÀÖµíÀÌ ÇÔ¼ö semctlÀº msgctlº¸´Ù ÈξÀ º¹ÀâÇÏ´Ù. 
     sem_id´Â À¯È¿ÇÑ ¼¼¸¶Æ÷¾î ½Äº°ÀÚ¶ó¾ß ÇÑ´Ù. 
     command´Â msgctl¿¡¼­¿Í °°ÀÌ ¼öÇàÇØ¾ß ÇÒ Á¤È®ÇÑ ±â´ÉÀ» ¸í½ÃÇÑ´Ù. 
     ÀÌ ±â´É¿¡´Â ¼¼°¡Áö À¯ÇüÀÌ ÀÖ´Ù. IPC_STAT¿Í °°Àº Ç¥ÁØ IPC±â´É,
     ´ÜÀÏ ¼¼¸¶Æ÷¾î¸¸À» ´Ù·ç´Â ±â´É, ¼¼¸¶Æ÷¾îÀÇ Àüü¸¦ ´Ù·ç´Â ±â´ÉÀÌ ±×°ÍÀÌ´Ù. 
     °¡´ÉÇÑ ¸ðµç ±â´ÉÀ» ´ÙÀ½°ú °°ÀÌ Á¤¸®ÇÏ¿´´Ù.
                    
                   semctl(semaphore control operations) ±â´É ÄÚµå
   -----------------------------------------------------------------------------
         Ç¥ÁØ IPC±â´É (semid_ds±¸Á¶´Â sem.h¿¡ Á¤ÀǵǾî ÀÖ´Ù.)
   ----------------------------------------------------------------------------- 
         IPC_STAT  »óÅÂÁ¤º¸¸¦ ctl_arg.stat¿¡ ÀúÀåÇÑ´Ù.
         IPC_SET   ctl_arg.stat¿¡ ÀúÀåµÈ ÇüÅ·Π¼ÒÀ¯±Ç°ú »ç¿ë Çã°¡±ÇÀ» ÁöÁ¤ÇÑ´Ù.
         IPC_RMID  ½Ã½ºÅÛ¿¡¼­ ÇØ´ç ¼¼¸¶Æ÷¾îÀÇ ÁýÇÕÀ» »èÁ¦ÇÑ´Ù.
   ----------------------------------------------------------------------------- 
         ´ÜÀÏ ¼¼¸¶Æ÷¾î ¿¬»ê (À̵éÀº retval¿¡°Ô ³Ñ¾î¿Â °ª sem_unmÀ» »ç¿ëÇÑ´Ù.)
   ----------------------------------------------------------------------------- 
         GETVAL    ¼¼¸¶Æ÷¾îÀÇ °ª semvalÀ» µ¹·ÁÁØ´Ù.
         SETVAL    ¼¼¸¶Æ÷¾î °ªÀ» ctl_arg.val·Î ÁöÁ¤ÇÑ´Ù.
         GETPID    sempidÀÇ °ªÀ» µ¹·ÁÁØ´Ù.
         GETNCNT   semncnt¸¦ µ¹·ÁÁØ´Ù.
         GETZCNT   semzcnt¸¦ µ¹·ÁÁØ´Ù.
   ----------------------------------------------------------------------------- 
         Àüü ¼¼¸¶Æ÷¾î ¿¬»ê 
   ----------------------------------------------------------------------------- 
         GETALL    ¸ðµç senvalsÀÇ °ªÀ» ctl_arg.array¿¡ ÀúÀåÇÑ´Ù.
         SETALL    ctl_arg.arrayÀÇ °ªÀ» »ç¿ëÇÏ¿© ¸ðµç semvals°ªÀ» ÁöÁ¤ÇÑ´Ù.
   ----------------------------------------------------------------------------- 
    
      sem_num Àμö´Â semctlÀÇ ´ÜÀÏ ¼¼¸¶Æ÷¾î ±â´É¿¡¼­ ƯÁ¤ ¼¼¸¶Æ÷¾î¸¦ ÁöÁ¤ÇØÁØ´Ù.
      ¸¶Áö¸· ÀμöÀÎ ctl_arg´Â ¼¼°¡Áö ±¸¼º ¿ä¼ÒÀÇ °áÇÕÀÌ´Ù. 
      ÀÌµé ±¸¼º ¿ä¼ÒµéÀº °¢°¢ semctlÀÇ ¼¼°¡Áö ±â´É¿¡ ´ëÀÀÇÑ´Ù.
      semctlÀº ¼¼¸¶Æ÷¾îÀÇ ÃʱⰪÀ» ÁöÁ¤ÇÒ ¶§ ¿ä±äÇÏ°Ô »ç¿ëµÈ´Ù. 
      ÀÌ ±â´ÉÀº semget¿¡´Â ¾øÀ½¿¡ ÁÖÀÇÇ϶ó.
      µû¶ó¼­ semget°ú semctlÀº µÎ°³ ¸ðµÎ ÀÖ¾î¾ß ÇÑ´Ù.
      ´ÙÀ½¿¡ ¿¹·Î¼­ Á¦½ÃÇÏ´Â ÇÔ¼ö´Â ÇÁ·Î±×·¥ÀÌ ´ÜÀÏ ¼¼¸¶Æ÷¾î¸¦ »ý¼ºÇÒ¶§³ª 
      ÀÌ¿¡ ´ëÇÑ ¼¼¸¶Æ÷¾î ÁýÇÕ ½Äº°ÀÚ¸¦ ¾ò°íÀÚ ÇÒ ¶§ »ç¿ëµÉ ¼ö ÀÖ´Ù. 
      ¼¼¸¶Æ÷¾î°¡ »ý¼ºµÇ´Â °æ¿ì¿¡´Â semctlÀ» »ç¿ëÇÏ¿© ÃʱⰪÀ» ºÎ¿©ÇÏ°Ô µÈ´Ù.

   /* initsem  -- semaphore initialization */
   #include "pv.h"
    initsem(semkey)
    key_t semkey;
    {
          int status = 0, semid ;
          if ((semid = semget(semkey, 1, SEMPERM|IPC_CREAT|IPC_EXCL)) == -1) {
               if (errno == EEXIST)
                   semid = semget(semkey, 1, 0);
          }else   /* if created... */
               status = semctl(semid, 0, SETVAL, 1);

        if ((semid == -1 || status == -1) {
             perror("initsem failed");
             return (-1);
        }else
             return semid;    /* all okay  */
     }  

  include È­ÀÏ pv.h´Â ´ÙÀ½°ú °°´Ù.
 
    /* semaphore example header file */
    #include 
    #include 
    #include 
    #include 
    extern int errno;
    #define SEMPERM 0600
    #define TRUE 1
    #define FALSE 0 

   ¼¼¸¶Æ÷¾î ¿¬»ê : semop È£Ãâ
 - semop È£Ãâ semopÀº ±âº»ÀûÀÎ ¼¼¸¶Æ÷¾î ¿¬»êÀ» ½ÇÁ¦·Î ¼öÇàÇÏ´Â ½Ã½ºÅÛÈ£ÃâÀÌ´Ù.
   À̶§ semopÀº ¸Þ´º¾óÀÇ Ç׸ñÀÌ ¾Æ´Ï¶ó ½ÇÁ¦ ÇÔ¼ö À̸§ÀÌ´Ù.
   »ç¿ë¹ý 
      #include 
      #include 
      #include 
      int retval, sem_id;
      struct sembuf op_array[SOMEVALUE];
               .
               .
      retval = semop(sem_id, op_array, SOMEVALUE);

   sem_id´Â ¼¼¸¶Æ÷¾î ÁýÇÕ ½Äº°Àڷμ­ ÀÌÀü¿¡ semgetÈ£ÃâÀ» ÅëÇØ °ªÀÌ ÁöÁ¤µÇ¾î¾ß 
   ÇÑ´Ù. op_array´Â sembuf±¸Á¶ÀÇ ¹è¿­·Î¼­ sembuf±¸Á¶´Â sem.h¿¡ Á¤ÀǵǾî ÀÖ´Ù.
   SOMEVALUE´Â ÀÓÀÇÀÇ Á¤¼öÇü »ó¼öÀÌ´Ù. 
   °¢°¢ÀÇ sembuf±¸Á¶ º¯¼ö´Â ¼¼¸¶Æ÷¾î¿¡ ´ëÇØ ¼öÇàÇÒ ¿¬»êÀ» ÁöÁ¤ÇÑ´Ù.
   ´Ù½Ã °­Á¶ÇÏ°Å´Ï¿Í semopÇÔ¼ö°¡ ¼¼¸¶Æ÷¾î ÁýÇÕ¿¡ ´ëÇØ ¼öÇàÇÏ´Â ÀÏ·ÃÀÇ ¿¬»êµéÀº 
   ¸ðµÎ ¿øÀÚÈ­ µÇ¾î¾ß ÇÑ´Ù. Áï, ±×ÁßÀÇ ÇÑ ¿¬»êÀÌ¶óµµ ¼öÇàÇÒ ¼ö ¾ø´Ù¸é Àüü ¿¬»ê
   ÀÌ ¸ðµÎ ¼öÇàµÇÁö ¸»¾Æ¾ß ÇÑ´Ù. ÀÌ °æ¿ì¿¡´Â Ưº°È÷ ¸í½ÃµÇÁö ¾Ê´ÂÇÑ, 
   ¸ðµç ¿¬»êÀÌ Çѹø¿¡ ¼öÇàµÉ¼ö ÀÖÀ»¶§±îÁö ÇÁ·Î¼¼½ºÀÇ ¼öÇàÀÌ ÁßÁöµÈ´Ù.
   sembuf±¸Á¶¸¦ Á»´õ ÀÚ¼¼È÷ º¸¸é ´ÙÀ½°ú °°ÀÌ ±¸¼ºµÇ¾î ÀÖ´Ù.
  
      --------------------------------------------------------------------
      |     struct sembuf {                                              |
      |     short   sem_num;        /* semaphore # */                    |
      |     short   sem_op;         /* semaphore operation */            |
      |     short   sem_flg;        /* operation flags */                |
      --------------------------------------------------------------------
 
   sem_num´Â ÁýÇÕ ³»ÀÇ ¼¼¸¶Æ÷¾î¿¡ ´ëÇÑ Ã·ÀÚ¸¦ ÀúÀåÇÑ´Ù. ¸¸¾à ÁýÇÕÀÇ ¿ø¼Ò°¡ 
   Çϳª»ÓÀ̶ó¸é sem_numÀÇ °ªÀº 0À̾î¾ß ÇÑ´Ù.  sem_op´Â ÇÔ¼ö semopÀÌ ¼öÇàÇØ¾ß 
   ÇÏ´Â ±â´ÉÀ» Á¤¼ö·Î¼­ ³ªÅ¸³½´Ù.
   ¿©±â¿¡´Â ¼¼°¡Áö °æ¿ì°¡ ÀÖ´Ù.

   °æ¿ì 1 : sem_op°¡ À½¼öÀ϶§

   ÀÌ °æ¿ì¿¡´Â ¾Õ¼­ ¼Ò°³ÇßµíÀÌ ÀϹÝÀûÀÎ ¼¼¸¶Æ÷¾î ¸í·É P()¿Í °°ÀÌ ¼öÇàµÈ´Ù. 
   À̸¦ ÀÇ»ç ÄÚµå(pseudo-code)·Î ³ªÅ¸³»¸é ´ÙÀ½°ú °°´Ù 
  (ABS´Â º¯¼öÀÇ Àý´ë°ªÀ» ³ªÅ¸³½´Ù)
 
        if (semval >= ABS(sem_op)){
             set semval to semval-ABS(sem_op)
        } else {
             if ((sem_flg&IPC_NOWAIT))
                     return-1 immediately
             else{
                    wait until semval reaches or exceeds
                    ABS(sem_op), then subtract
                    ABS(sem_op) as above
                  }
           }
   ±âº» °³³äÀº ÇÔ¼ö semop¿¡¼­ sem_numÀÌ °¡¸®Å°´Â ¼¼¸¶Æ÷¾îÀÇ °ª semvalÀ» 
   Á¶»çÇÏ´Â °ÍÀÌ´Ù.
   semvalÀÇ °ªÀÌ ÃæºÐÈ÷ Å©´Ù¸é Áï½Ã Çϳª °¨¼Ò½ÃŲ´Ù. ¾Æ´Ï¸é semvalÀÌ ÃæºÐÈ÷ 
   Ä¿Áú ¶§±îÁö ÇÁ·Î¼¼½ºÀÇ ¼öÇàÀ» ÁߴܽÃŲ´Ù. ±×·¯³ª sem_flgÀÇ IPC_NOWAIT
   Ç÷¡±×ÀÇ °ªÀÌ 1·Î µÇ¾î ÀÖÀ¸¸é sem_opÀº Áï½Ã -1À» µÇµ¹·ÁÁÖ°í errono°ªÀ» 
   EAGAINÀ¸·Î ÇÑ´Ù.

   °æ¿ì 2 : sem_opÀÌ ¾ç¼öÀÏ ¶§

   À̶§´Â º¸ÅëÀÇ V()¿¬»ê°ú À¯»çÇÏ´Ù. Áï sem_opÀÇ °ªÀ» ÇØ´ç semval¿¡ ´õÇØÁØ´Ù.
   À̶§ ÇØ´ç ¼¼¸¶Æ÷¾îÀÇ °ªÀÌ Áõ°¡Çϱ⸦ ±â´Ù¸®´Â ÇÁ·Î¼¼½ºµéÀÌ ±ú¾î³ª°Ô µÈ´Ù.
    
   °æ¿ì 3 : sem_opÀÌ 0À϶§

   ÀÌ °æ¿ì´Â semvalÀ» º¯È¯½ÃÅ°´Â °ÍÀÌ ¾Æ´Ï¶ó °ªÀÌ 0ÀÌ µÉ¶§±îÁö ±â´Ù¸°´Ù.
   semvalÀÌ 0ÀÌ ¾Æ´Ï°í sem_flgÀÇ IPC_NOWAIT°¡ 1ÀÎ °æ¿ì¿¡ semop´Â Áï½Ã ¿À·ù 
   °ªÀ» µ¹·ÁÁÖ°Ô µÈ´Ù.
         
   SEM_UNDO Ç÷¡±×

   - ÀÌ°ÍÀº sembuf±¸Á¶ÀÇ ±¸¼º¿ä¼Ò sem_flg¿¡ ÀÖ´Â Ç÷¡±×ÀÇ ÇϳªÀÌ´Ù. 
     ÀÌ´Â ÇÁ·Î¼¼½ºÀÇ ¼öÇàÀÌ ³¡³µÀ» ¶§ ½Ã½ºÅÛÀÌ ¼öÇàµÈ ¿¬»êÀ» ÀÚµ¿ÀûÀ¸·Î 
     Ãë¼ÒÇϵµ·Ï Áö½ÃÇÑ´Ù. ¼öÇàµÈ ÀÏ·ÃÀÇ ¿¬»êÀ» ÃßÀûÇϱâ À§ÇÏ¿© ½Ã½ºÅÛÀº 
     ¼¼¸¶Æ÷¾î¿¡ semadj¶ó´Â Á¤¼ö¸¦ ´ëÀÀ½ÃŲ´Ù. 
     À̶§ semadjº¯¼ö´Â ÇÁ·Î¼¼½º¸¶´Ù ÇÒ´çµÇ¾î¾ß ÇÔ¿¡ ÁÖÀÇÇضó.  
     µû¶ó¼­ ¼­·Î ´Ù¸¥ ÇÁ·Î¼¼¼­´Â µ¿ÀÏÇÑ ¼¼¸¶Æ÷¾î¿¡ ´ëÇØ µ¶¸³ÀûÀÎ semadj°ªÀ» 
     À¯ÁöÇÏ°Ô µÈ´Ù. SEM_UNDOÀÇ °ªÀ» 1·Î ÇÏ°í¼­ semop¿¬»êÀ» ¼öÇàÇϸé 
     semadj°ª¿¡¼­ sem_num°ªÀ» »«´Ù.
     À̶§ sem_numÀÇ ºÎÈ£°¡ Áß¿äÇѵ¥ ÀÌ´Â sem_numÀÇ °ªÀÌ ¾ç¼öÀΰ¡ À½¼öÀΰ¡¿¡ 
     µû¶ó semadjÀÇ °ªÀÌ °¨¼ÒÇϰųª Áõ°¡Çϱ⠶§¹®ÀÌ´Ù. ÇÁ·Î¼¼½ºÀÇ ¼öÇàÀÌ ³¡³ª¸é 
     ½Ã½ºÅÛÀº semadj°ªÀ» ÇØ´ç ¼¼¸¶Æ÷¾î¿¡ ´õÇØÁÜÀ¸·Î½á Áö±Ý±îÁöÀÇ ¸ðµç 
     semopÈ£Ãâ È¿°ú¸¦ »ó¼â½ÃŲ´Ù. ÀϹÝÀûÀ¸·Î º¼¶§ ÇÁ·Î¼¼½º°¡ ÁöÁ¤ÇÑ °ªÀÌ 
     ÇØ´ç ÇÁ·Î¼¼½ºÀÇ Á¾·á ÈÄ¿¡µµ È¿·ÂÀ» °®Áö ¾Ê´Â´Ù¸é SEM_UNDO°¡ »ç¿ëµÇ¾î¾ß¸¸ 
     ÇÑ´Ù.

   ¼¼¸¶Æ÷¾îÀÇ ¿¹

   - ÀÌÁ¦ initsem·çƾÀ¸·Î ½ÃÀÛÇÑ ¿¹¸¦ ¿Ï¼ºÇØ º¸ÀÚ. ¿©±â¼­´Â ÀüÅëÀûÀÎ ¼¼¸¶Æ÷¾î 
     ¿¬»êÀ» P()¿Í V()·Î ±¸ÇöÇÏ¿© À̸¦ Áß½ÉÀ¸·Î »ï¾Ò´Ù. ¿ì¼± P()¸¦ º¸ÀÚ.

       /* pc -- semaphore p operation */
       #include "pv.h"
       p(semid)
       int semid;
       {
           struct sembuf p_buf;
           p_buf.sem_num = 0;
           p_buf.sem_op = -1;
           p_buf.sem_flg = SEM_UNDO;
          
           if (semop(semid, &p_buf, 1) == -1) {
               perror("p(semid) failed");
               exit(1);
           } else
               return(0);
        } 

     À̶§ SEM_UNDO¸¦ »ç¿ëÇßÀ½¿¡ ÁÖÀÇÇ϶ó. V()´Â ´ÙÀ½°ú °°´Ù.
      
        /* v.c -- semaphore v operation */
        #include "pv.h"
        v(semid)
        int semid;
        {
            struct sembuf v_buf;
            v_buf.sem_num = 0; 
            v_buf.sem_op = 1; 
            v_buf.sem_flg = SEM_UNDO; 
  
            if(semop(semid, &v_buf, 1) == -1) {
                perror("v(semid) failed");
                exit(1);
            } else
                return(0);
         }

     ÀÌÁ¦ ºñ±³Àû °£´ÜÇÑ ÀÌµé ·çƾÀ¸·Î »óÈ£ ¹èÁ¦¸¦ ±¸ÇöÇغ¸ÀÚ.
     ´ÙÀ½ÀÇ ÇÁ·Î±×·¥À» »ìÆ캸ÀÚ.
 
         /* testsem -- test semaphore routines */
         #include "pv.h"
         
         main()
         {
              key_t semkey = 0x200;
              
              if(fork() == 0)
                 handlesem(semkey);

              if(fork() == 0)
                 handlesem(semkey);

              if(fork() == 0)
                 handlesem(semkey);
          }
             
          handlesem(skey)
          key_t skey;
          {
              int semid, pid = getpid();
 
              if((semid = initsem(skey)) < 0)
                  exit(1);
              printf("\nprocess %d before critical section\n", pid);
        
              p(semid);
              printf("process %d in critical section\n", pid);
             
              /* in real life do something interesting */
              sleep(10);
              printf("process %d leaving critical section\n", pid);

              v(semid);
              printf("process %d exiting\n", pid);
              exit(0);
           }
     testsemÀº ¼¼°³ÀÇ ÀÚ½ÄÇÁ·Î¼¼½º¸¦ »ý¼ºÇÏ°í , À̵éÀº p()¿Í v()¸¦ »ç¿ëÇÏ¿© 
     ÀÓ°è ¿µ¿ª¿¡´Â ÇÑ ¼ø°£¿¡ µÑ ÀÌ»óÀÌ µé¾îÀÖÁö ¸øÇϵµ·Ï ÇÑ´Ù. 
     ÇÑ ÄÄÇ»ÅÍ¿¡¼­ testsemÀ» ¼öÇà½ÃŲ °á°ú´Â ´ÙÀ½°ú °°´Ù.

              process 799 before critical section 
              process 800 before critical section 
              process 801 before critical section 
 
              process 799 in critical section 
              process 799 leaving critical section 
              process 799 exiting 
              process 801 in critical section 
              process 801 leaving critical section 
              process 801 exiting
              process 800 in critical section 
              process 800 leaving critical section 
              process 800 exiting
                



o Critical secion ¶õ ?

  - ´ÙÁß ÇÁ·Î±×·¡¹Ö ¿î¿µÃ¼Á¦¿¡¼­ ¿©·¯ ÇÁ·Î¼¼½º°¡ µ¥ÀÌŸ¸¦ °øÀ¯Çϸ鼭 ¼öÇàµÉ ¶§ 
    °¢ ÇÁ·Î¼¼½º¿¡¼­ °øÀ¯ µ¥ÀÌŸ¸¦ ¾×¼¼½ºÇÏ´Â ÇÁ·Î±×·¥ ÄÚµå ºÎºÐÀ» °¡¸®Å°´Â ¸».
    °øÀ¯µ¥ÀÌŸ¸¦ ¿©·¯ ÇÁ·Î¼¼½º°¡ µ¿½Ã¿¡ ¾×¼¼½ºÇÏ¸é ½Ã°£ÀûÀÎ Â÷ÀÌ ¶§¹®¿¡ À߸øµÈ 
    °á°ú¸¦ ¸¸µé¾î ³¾ ¼ö Àֱ⠶§¹®¿¡ ÇÑ ÇÁ·Î¼¼½º°¡ À§Çè ºÎºÐÀ» ¼öÇàÇÏ°í ÀÖÀ» ¶§,
    Áï °øÀ¯ µ¥ÀÌŸ¸¦ ¾×¼¼½ºÇÏ°í ÀÖÀ» ¶§´Â ´Ù¸¥ ÇÁ·Î¼¼½ºµéÀº Àý´ë·Î ±× µ¥ÀÌŸ¸¦
    ¾×¼¼½ºÇÏÁö ¸øÇϵµ·Ï ÇÏ¿©¾ß ÇÑ´Ù.

o Mutual exclusion (»óÈ£ ¹èÁ¦)¶õ(1) ?

  - ÇÁ·Î¼¼½ºÀÇ »óÈ£ ±³½Å¿¡ ´ëÇÑ ±âº»ÀûÀÎ Á¶Ä¡´Â °ø¿ë ºÎºÐÀ» ¿©·¯ ÇÁ·Î¼¼½º°¡ 
    µ¿½Ã¿¡ »ç¿ëÇÏ´Â °ÍÀ» ¹èÁ¦ÇÏ´Â °ÍÀ̾ú´Ù. ½Ã½ºÅÛÀÇ ¾î¶°ÇÑ ÀÚ¿øÀ» ÇÑ ½ÃÁ¡¿¡¼­
    ÇÑ°³ÀÇ ÇÁ·Î¼¼½º¸¸ÀÌ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ÇÏ´Â °ÍÀ» »óÈ£¹èÁ¦¶ó ÇÑ´Ù. ¶ÇÇÑ, 
    ÇÁ·Î±×·¥¿¡¼­ ÀÌ·¯ÇÑ ÀÚ¿øÀ» »ç¿ëÇϰųª ȤÀº ±× ³»¿ëÀ» º¯°æÇÏ´Â ºÎºÐÀ» 
    À§ÇèºÎºÐ (critical section)À̶ó Çϸç, µÑ ÀÌ»óÀÇ ÇÁ·Î±×·¥¿¡¼­ ÀÌ À§Çè 
    ºÎºÐÀÌ µ¿½Ã¿¡ ¼öÇàµÇÁö ¾Êµµ·Ï ÇÏ´Â °ÍÀÌ »óÈ£ ¹èÁ¦ÀÇ ±â´ÉÀÌ´Ù.  

o Mutual exclusion (»óÈ£ ¹èÁ¦)¶õ(2) ?

  - ´ÙÁß ÇÁ·Î±×·¡¹Ö ½Ã½ºÅÛ¿¡¼­ ¿©·¯ ÇÁ·Î¼¼½º°¡ ÇϳªÀÇ °øÀ¯ µ¥ÀÌŸ¸¦ ¾×¼¼½ºÇϸ鼭
    ÀÛ¾÷À» ÇÒ ¶§, ÇÑ ÇÁ·Î¼¼½º°¡ ±× µ¥ÀÌŸ¸¦ ¾×¼¼½ºÇÒ ¶§´Â ´Ù¸¥ ÇÁ·Î¼¼½ºµéÀº 
    ±×°ÍÀ» »ç¿ëÇÏÁö ¸øÇϵµ·Ï ÇÏ´Â ¿î¿µÃ¼Á¦ÀÇ ±â´É.
    ¿¹¸¦ µé¾î ÇÑ ÇÁ·Î¼¼½º°¡ ¾î¶² È­ÀÏ¿¡ µ¥ÀÌŸ¸¦ ¾²°í ÀÖÀ» ¶§ ´Ù¸¥ ÇÁ·Î¼¼½º°¡ 
    ±× È­ÀÏÀ» Áö¿ø¹ö¸°´Ù¸é ¸¹Àº ¹®Á¦°¡ ¹ß»ýÇÒ °ÍÀÌ´Ù. »óÈ£ ¹èÁ¦´Â Çѹø¿¡ 
    ÇÑ ÇÁ·Î¼¼½º¸¸ÀÌ °øÀ¯ µ¥ÀÌŸ¸¦ ¾×¼¼½ºÇÒ ¼ö ÀÖµµ·Ï ÇØ ÁÖ´Â °ÍÀ¸·Î, 
    ´ÙÁßÇÁ·Î±×·¡¹Ö ½Ã½ºÅÛÀÇ ¿î¿µÃ¼Á¦°¡ ²À °®Ãß¾î¾ß ÇÒ ±â´ÉÀÌ´Ù.
  
 
      
Revision History

ÀÛ¼ºÀÏÀÚ : 96.10.10
ÀÛ¼ºÀÚ : ÀÌÁø¼ö

¼öÁ¤ÀÏÀÚ :
¼öÁ¤ÀÚ :