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 ÀÛ¼ºÀÚ : ÀÌÁø¼ö ¼öÁ¤ÀÏÀÚ : ¼öÁ¤ÀÚ :