´ÙÀ½ À§·Î ÀÌÀü ¸ñÂ÷ ¸®´ª½º ÇÁ·Î±×·¡¸Ó¸¦ À§ÇÑ °¡À̵å

½Ã½ºÅÛ È£Ãâ:semctl() (SYSTEM CALL:semctl())


  SYSTEM CALL: semctl();                                                          
  PROTOTYPE: int semctl ( int semid, int semnum, int cmd, union semun arg );
    RETURNS: positive integer on success 
             -1 on error: errno = EACCESS (permission denied)
                                  EFAULT (invalid address pointed to by arg argument)
                                  EIDRM (semaphore set was removed)
                                  EINVAL (set doesn't exist, or semid is invalid)
                                  EPERM (EUID has no privileges for cmd in arg)
                                  ERANGE (semaphore value out of range)
  NOTES: Performs control operations on a semaphore set

semctl ½Ã½ºÅÛ È£ÃâÀº ¼¼¸¶ÆÛ ÁýÇÕ¿¡¼­ ÅëÁ¦ µ¿ÀÛ(control operation)À» ¼öÇàÇϴµ¥ »ç¿ëµÈ´Ù. ÀÌ È£ÃâÀº ¸Þ¼¼Áö Å¥¿¡ ´ëÇØ µ¿ÀÛÀ» ¼öÇàÇϴµ¥ »ç¿ëµÇ´Â msgctl ½Ã½ºÅÛ È£Ãâ°ú À¯»çÇÏ´Ù. µÎ°³ÀÇ ½Ã½ºÅÛ È£ÃâÀÇ ¾Æ±Ô¸ÕÆ® ¸ñ·ÏÀ» ºñ±³Çغ¸¸é, semctlÀÇ ¸ñ·ÏÀÌ msgctl°ú Á¶±Ý ´Ù¸§À» ¾Ë ¼ö ÀÖ´Ù. ¼¼¸¶ÆÛ´Â ½ÇÁ¦·Î ´ÜÀÏ °³Ã¼¶ó±â º¸´Ù´Â ÁýÇÕÀ¸·Î ±¸ÇöµÊÀ» ±â¾ïÇ϶ó. ¼¼¸¶ÆÛ µ¿ÀÛ¿¡ ´ëÇؼ­ IPC Å°¸¦ ³Ñ°Ü¾ßÇÒ ÇÊ¿ä´Â ¾øÀ» »Ó¸¸¾Æ´Ï¶ó ¸ñÀûÁö(target) ¼¼¸¶ÆÛ´Â ´ç¿¬È÷ ÁýÇվȿ¡ ÀÖ¾î¾ß ÇÑ´Ù.

¸í·É¾î¸¦ ÁöÁ¤ÇϱâÀ§ÇØ cmd ¾Æ±Ô¸ÕÆ®¸¦ »ç¿ëÇÏ´Â µÎ ½Ã½ºÅÛ È£ÃâÀº IPC °´Ã¼¿¡¼­ ¼öÇàµÈ´Ù. ³²°ÜÁø Â÷ÀÌÁ¡Àº µÎ È£ÃâÀÇ ¸¶Áö¸· ¾Æ±Ô¸ÕÆ®ÀÌ´Ù. msgctl¿¡¼­ ¸¶Áö¸· ¾Æ±Ô¸ÕÆ®´Â Ä¿³Î¿¡¼­ »ç¿ëµÇ´Â ³»ºÎ ÀÚ·á ±¸Á¶ÀÇ º¹»çº»À» ³ªÅ¸³½´Ù. Å¥ÀÇ ¼ÒÀ¯±Ç°ú Çã°¡»çÇ×À» ¹Ù²Ù°Å³ª ÁöÁ¤ÇÏ´Â °ÍÀº ¹°·ÐÀÌ°í ¸Þ¼¼Áö Å¥¿¡ ´ëÇÑ Á¤º¸¸¦ Á¶È¸ÇϱâÀ§ÇØ ÀÌ ±¸Á¶Ã¼¸¦ »ç¿ëÇßÀ½À» »ó±âÇ϶ó. ¼¼¸¶ÆÛ¿¡¼­´Â ºÎ°¡ÀûÀÎ µ¿ÀÛ ¸í·É¾î¸¦ Áö¿øÇϱâÀ§ÇØ ¸¶Áö¸· ¾Æ±Ô¸ÕÆ®·Î º¸´Ù º¹ÀâÇÑ ÀÚ·á ŸÀÔÀÌ ¿ä±¸µÈ´Ù. unionÀÇ »ç¿ëÀº Áß¿äÇÑ ´Ü°è¿¡¼­ ¸¹Àº Ãʺ¸ ¼¼¸¶ÆÛ ÇÁ·Î±×·¡¸ÓµéÀ» ´çȲÇÏ°Ô ¸¸µç´Ù. ÀÌ·¯ÇÑ È¥µ¿À» ¸·±âÀ§ÇØ ÀÌ ±¸Á¶Ã¼¸¦ ÁÖÀDZí°Ô ÇغÎÇÒ °Í ÀÌ´Ù.

semctl()ÀÇ Ã¹¹ø° ¾Æ±Ô¸ÕÆ®´Â semget È£Ãâ¿¡ ÀÇÇØ ¹ÝȯµÈ Å°°ªÀÌ´Ù. µÎ¹ø° ¾Æ±Ô¸ÕÆ®(semnu)´Â µ¿ÀÛÀÇ ¸ñÇ¥°¡ µÇ´Â ¼¼¸¶ÆÛ ¹øÈ£ÀÌ´Ù. Áß¿äÇÑ °ÍÀº, ÀÌ°ÍÀÌ '0'°ªÀ¸·Î Ç¥ÇöµÇ´Â ÁýÇÕ³»ÀÇ Ã¹¹ø° ¼¼¸¶ÆÛ(¶Ç´Â ¿ÀÁ÷ ÇÑ°³¸¸ ÀÖ´Â °æ¿ì)¸¦ °¡Áö°í ¼¼¸¶ÆÛ ÁýÇÕÀÇ À妽º·Î °£Áֵȴٴ °ÍÀÌ´Ù.

cmd ¾Æ±Ô¸ÕÆ®´Â ÁýÇÕ¿¡ ´ëÇؼ­ ¼öÇàµÇ¾îÁö´Â ¸í·É¾î¸¦ ³ªÅ¸³½´Ù. Àß ¾Ë·ÁÁø IPC_STAT/IPC_SET ¸í·É¾î´Â ¼¼¸¶ÆÛ ÁýÇÕ¿¡¼­ ÁöÁ¤µÇ´Â ºÎ°¡ÀûÀÎ ¸í·É¾îÀÇ Ç³ºÎÇÔ°ú ÇÔ²² Ç¥ÇöµÈ´Ù.:

IPC_STAT
ÁýÇÕ¿¡ ´ëÇÑ semid_ds ±¸Á¶¸¦ Á¶È¸ÇÏ°í, semun union¾ÈÀÇ buf ¾Æ±Ô¸ÕÆ®ÀÇ ÁÖ¼ÒÁö¿¡ ÀúÀåÇÑ´Ù.
IPC_SET
ÁýÇÕ¿¡ ´ëÇÑ semid_ds ±¸Á¶ÀÇ ipc_perm ¸â¹öÀÇ °ªÀ» ÁöÁ¤ÇÑ´Ù. semum unionÀÇ buf ¾Æ±Ô¸ÕÆ®·Î ºÎÅÍ °ªÀ» °¡Á®¿Â´Ù.
IPC_RMID
Ä¿³Î·Î ºÎÅÍ ÁýÇÕÀ» Á¦°ÅÇÑ´Ù.
GETALL
ÁýÇÕÀ¸·Î ºÎÅÍ ¸ðµç ¼¼¸¶ÆÛÀÇ °ªÀ» ¾ò´Âµ¥ »ç¿ëµÈ´Ù. Á¤¼ö°ªµéÀÌ unionÀÇ ¹è¿­ ¸â¹ö¿¡ ÀÇÇØ ÁöÁ¤µÈ unsigned short integer ¹è¿­¿¡ ÀúÀåµÈ´Ù.
GETCNT
ÀÚ¿ø¿¡ ´ëÇØ ÇöÀç ±â´Ù¸®°í ÀÖ´Â ÇÁ·Î¼¼½ºÀÇ ¼ö¸¦ ¹ÝȯÇÑ´Ù.
GETPID
¸¶Áö¸· semop È£ÃâÀ» ¼öÇàÇÑ ÇÁ·Î¼¼½ºÀÇ PID¸¦ ¹ÝȯÇÑ´Ù.
GETZCNT
100% ÀÚ¿ø È°¿ëÀ» À§ÇØ ÇöÀç ±â´Ù¸®°í ÀÖ´Â ÇÁ·Î¼¼½ºÀÇ ¼ö¸¦ ¹ÝȯÇÑ´Ù.
SETALL
ÁýÇÕ¾ÈÀÇ ¸ðµç ¼¼¸¶ÆÛÀÇ °ªÀ» unionÀÇ ¹è¿­ ¸â¹ö¾È¿¡ Æ÷ÇÔµÈ ¸ÅĪµÇ´Â °ªÀ¸·Î ÁöÁ¤ÇÑ´Ù.
SETVAL
ÁýÇÕ¾ÈÀÇ °³º°ÀûÀÎ ¼¼¸¶ÆÛÀÇ °ªÀ» unionÀÇ val ¸â¹öÀÇ °ªÀ¸·Î ÁöÁ¤ÇÑ´Ù.
arg ¾Æ±Ô¸ÕÆ®´Â semun ŸÀÔÀÇ ¿¹¸¦ ³ªÅ¸³½´Ù. ÀÌ Æ¯º°ÇÑ ¿¬ÇÕü(union)´Â linux/sem.h¿¡ ´ÙÀ½°ú °°ÀÌ ¼±¾ðµÇ¾îÀÖ´Ù.:


        /* semctl ½Ã½ºÅÛ È£Ãâ¿¡ ´ëÇÑ ¾Æ±Ô¸ÕÆ® */
        union semun {
                int val;                /* SETVALÀ» À§ÇÑ °ª */
                struct semid_ds *buf;   /* IPC_STAT & IPC_SETÀ» À§ÇÑ ¹öÆÛ */
                ushort *array;          /* GETALL & SETALL¸¦ À§ÇÑ ¹è¿­ */
                struct seminfo *__buf;  /* IPC_INFO¸¦ À§ÇÑ ¹öÆÛ */
                void *__pad;
        };

val
SETVAL ¸í·É¾î°¡ ¼öÇàµÉ ¶§ »ç¿ëµÈ´Ù.¼¼¸¶ÆÛ¿¡ ÁöÁ¤µÉ °ªÀ» ÁöÁ¤ÇÑ´Ù.
buf
IPC_STAT/IPC_SET¿¡¼­ »ç¿ëµÈ´Ù. Ä¿³Î¾È¿¡¼­ »ç¿ëµÇ´Â ³»ºÎ ¼¼¸¶ÆÛ ÀÚ·á ±¸Á¶ÀÇ º¹»çº»À» ³ªÅ¸³½´Ù.
array
GETALL/SETALL ¸í·É¾î¿¡¼­ »ç¿ëµÇ´Â Æ÷ÀÎÅÍ. ÁýÇվȿ¡¼­ ¸ðµç ¼¼¸¶ÆÛ °ªµéÀ» Á¶È¸Çϰųª ÁöÁ¤Çϴµ¥ »ç¿ëµÇ´Â Á¤¼ö°ªµéÀÇ ¹è¿­À» °¡¸®Å°°í ÀÖ¾î¾ß ÇÑ´Ù.
³²¾ÆÀÖ´Â ¾Æ±Ô¸ÕÆ®ÀÎ _buf¿Í _pad´Â Ä¿³Î¾ÈÀÇ ¼¼¸¶ÆÛ Äڵ峻¿¡¼­ ³»ºÎÀûÀ¸·Î »ç¿ëµÇ¸ç ÀÀ¿ëÇÁ·Î±×·¥ °³¹ßÀÚ¿¡°Ô´Â °ÅÀÇ ¾µ¸ð°¡ ¾ø´Ù. »ç½Ç»ó, ÀÌ·± µÎ°³ÀÇ ¾Æ±Ô¸ÕÆ®´Â ¸®´ª½º ¿î¿µÃ¼Á¦¿¡¼­ ÁöÁ¤µÇ¸ç ´Ù¸¥ À¯´Ð½º ±¸Çö¿¡¼­´Â ãÀ» ¼ö ¾ø´Ù.

ÀÌ·± Ưº°ÇÑ ½Ã½ºÅÛ È£ÃâÀ» ¸ðµç ½Ã½ºÅÛ V IPC È£ÃâÀ» ÀÌÇØÇϴµ¥ °¡Àå ¾î·Á¿î Á¡À¸·Î ²ÅÀ» ¼ö ÀÖÀ¸¹Ç·Î,½ÇÁ¦·Î ÀÌ·¯ÇÑ ´Ù¾çÇÑ ¿¹¸¦ °Ë»çÇÒ °ÍÀÌ´Ù.

´ÙÀ½ÀÇ ÂªÀº ÄÚµå´Â ³Ñ°ÜÁø ¼¼¸¶ÆÛÀÇ °ªÀ» ¹ÝȯÇÑ´Ù. ¸¶Áö¸· ¾Æ±Ô¸ÕÆ®(union)Àº GETVAL ¸í·É¾î°¡ »ç¿ëµÉ ¶§ ¹«½ÃµÈ´Ù.:


int get_sem_val( int sid, int semnum )
{
        return( semctl(sid, semnum, GETVAL, 0));
}

ÇÁ¸°ÅÍ ¿¹Á¦¸¦ ´Ù½Ã »ìÆ캸±âÀ§ÇØ, ¸ðµÎ ´Ù¼¸°³ÀÇ ÇÁ¸°ÅÍ »óÅ°¡ ÇÊ¿äÇÏ´Ù°í °¡Á¤ÇØ º¸ÀÚ:


        #define MAX_PRINTERS 5

        printer_usage()
        {
                int x;

                for(x=0; x<MAX_PRINTERS; x++)
                        printf("Printer %d: %d\n\r", x, get_sem_val( sid, x ));
        }

»õ ¼¼¸¶ÆÛ °ªÀ» ÃʱâÈ­Çϴµ¥ »ç¿ëµÇ´Â ´ÙÀ½ÀÇ ÇÔ¼ö¸¦ »ìÆ캸ÀÚ:


void init_semaphore( int sid, int semnum, int initval)
{
        union semun semopts;    

        semopts.val = initval;
        semctl( sid, semnum, SETVAL, semopts);
}

semctlÀÇ Ã¹¹ø° ¾Æ±Ô¸ÕÆ®´Â ¿¬ÇÕü(union)ÀÇ Æ÷ÀÎÅÍ°¡ ¾Æ´Ï¶ó º¹»çº»ÀÓÀ» ÁÖ¸ñÇ϶ó. ¿ì¸®°¡ ¾Æ±Ô¸ÕƮó·³ ¿¬ÇÕü(union)ÀÇ Àç¹èÇÏ¿¡ ÀÖ´Â µ¿¾È, ÀÌ ½Ã½ºÅÛ È£ÃâÀÌ »ç¿ëµÉ ¶§ ¿ÀÈ÷·Á ÀϹÝÀûÀÎ ½Ç¼ö¸¦ º¸¿©ÁÙ ¼ö ÀÖ´Ù.

msgtool ÇÁ·ÎÁ§Æ®·Î ºÎÅÍ IPC_STAT¿Í IPC_SET ¸í·É¾î°¡ Å¥»óÀÇ Çã°¡»çÇ×À» º¯°æÇϴµ¥ »ç¿ëµÈ´Ù´Â °ÍÀ» ±â¾ïÇ϶ó. ÀÌ·± ¸í·É¾îµéÀÌ ¼¼¸¶ÆÛ ±¸Çö»ó¿¡¼­ Áö¿øµÇ´Â ¹Ý¸é¿¡ ±×°ÍµéÀÇ »ç¿ëÀº ³»ºÎ ÀÚ·á ±¸Á¶°¡ ´ÜÀÏ °³Ã¼º¸´Ù´Â ¿¬ÇÕü(union)ÀÇ ¸â¹ö·Î ºÎÅÍ º¹»çµÇ°í Á¶È¸µÇ´Â °Í°ú´Â ´Ù¼Ò ´Ù¸£´Ù. ÀÌ ÄÚµå¾È¿¡¼­ ¹ö±×¸¦ ãÀ» ¼ö Àְڴ°¡?


/* ¿ä±¸µÇ´Â Çã°¡»çÇ×Àº ÅؽºÆ®·Î ³Ñ°ÜÁ®¾ß ÇÑ´Ù. (ex: "660") */

void changemode(int sid, char *mode)
{
        int rc;
        struct semid_ds mysemds;

        /* ³»ºÎ ÀÚ·á ±¸Á¶ÀÇ ÇöÀç °ªÀ» ¾ò´Â´Ù */
        if((rc = semctl(sid, 0, IPC_STAT, semopts)) == -1)
        {
                perror("semctl");
                exit(1);
        }
                
        printf("Old permissions were %o\n", semopts.buf->sem_perm.mode);
                
        /* ¼¼¸¶ÆÛÀÇ Çã°¡»çÇ×À» ¹Ù²Û´Ù */
        sscanf(mode, "%o", &semopts.buf->sem_perm.mode);

        /* ³»ºÎ ÀÚ·á ±¸Á¶¸¦ ¾÷µ¥ÀÌÆ®ÇÑ´Ù */
        semctl(sid, 0, IPC_SET, semopts);

        printf("Updated...\n");
}

ÀÌ ÄÚµå´Â ÁýÇÕ¿¡ ´ëÇÑ ³»ºÎ ÀÚ·á ±¸Á¶ÀÇ ±¹¼ÒÀûÀÎ º¹»çº»À» ¸¸µé°í, Çã°¡»çÇ×À» ¼öÁ¤ÇÏ°í, Ä¿³Î¿¡ IPC_SETÀ» ¹ÝȯÇÏ°íÀÚ ÇÑ´Ù. ¾î·µç, semctlÀÇ Ã¹¹ø° È£ÃâÀº Áï°¢ EFAULT¸¦ ¹ÝȯÇϰųª ¸¶Áö¸· ¾Æ±Ô¸ÕÆ®(union!)¿¡ ´ëÇÑ À߸øµÈ ÁÖ¼Ò¸¦ ¹ÝȯÇÑ´Ù. °Ô´Ù°¡, ±× È£Ãâ·Î ºÎÅÍ ¿¡·¯¸¦ üũÇÏÁö ¾Ê¾Ò´Ù¸é, memory fault°¡ ¹ß»ýÇÑ´Ù. ¿Ö?

IPC_SET/IPC_STAT ¸í·É¾î°¡ ¿¬ÇÕü(union)ÀÇ buf ¸â¹ö¸¦ »ç¿ëÇÏ°í ÀÌ°ÍÀº semid_ds ŸÀÔÀÇ Æ÷ÀÎÅÍ(pointer)ÀÓÀ» ±â¾ïÇ϶ó. Æ÷ÀÎÅÍÀÇ Æ÷ÀÎÅÍÀÇ Æ÷ÀÎÅÍÀÇ Æ÷ÀÎÅÍ! buf ¸â¹ö´Â ¿ì¸®ÀÇ ÇÔ¼ö°¡ Àû´çÈ÷ ÀÏÇϱâ À§ÇÑ À¯È¿ÇÑ ÀúÀåÀ§Ä¡¸¦ °¡¸®Å°°í ÀÖ¾î¾ß¸¸ ÇÑ´Ù. º¸¿ÏµÈ ¹öÀüÀ» »ìÆ캸ÀÚ:


void changemode(int sid, char *mode)
{
        int rc;
        struct semid_ds mysemds;

        /* ³»ºÎ ÀÚ·á ±¸Á¶ÀÇ ÇöÀç °ªÀ» ¾ò´Â´Ù */

        /* ¸ÕÀú ¿ì¸®ÀÇ ±¹¼ÒÀûÀÎ º¹»çº»À» °¡¸®Å²´Ù! */
        semopts.buf = &mysemds;

        /* ´Ù½Ã Çѹø ½ÃµµÇØ º¸ÀÚ! */
        if((rc = semctl(sid, 0, IPC_STAT, semopts)) == -1)
        {
                perror("semctl");
                exit(1);
        }
                
        printf("Old permissions were %o\n", semopts.buf->sem_perm.mode);
                
        /* ¼¼¸¶ÆÛÀÇ Çã°¡»çÇ×À» ¹Ù²Û´Ù */
        sscanf(mode, "%o", &semopts.buf->sem_perm.mode);

        /* ³»ºÎ ÀÚ·á ±¸Á¶¸¦ ¾÷µ¥ÀÌÆ®ÇÑ´Ù */
        semctl(sid, 0, IPC_SET, semopts);

        printf("Updated...\n");
}


ÀÌÀü:½Ã½ºÅÛ È£Ãâ:semop() (SYSTEM CALL:semop()) ´ÙÀ½:semtool:»óÈ£ÀÛ¿ë ¼¼¸¶ÆÛ Á¶Á¾ÀÚ

Copyright (c) 1996,1997 by Euibeom.Hwang & SangEun.Oh All Rights Reserved

Email To:Webmaster , Another address
LAST UPDATE Nov 25,1997
Created Nov 25,1997