[http://www.tldp.org/LDP/lpg/lpg.html] [[TableOfContents]] == ¸®´ª½º ¿î¿µÃ¼Á¦ (The Linux operating system) == 1991³â 3¿ù Linus Benedict Torvalds´Â ÀÚ½ÅÀÇ AT 386 ÄÄÇ»ÅÍ¿ëÀ¸·Î ¸ÖƼŽºÅ· ½Ã½ºÅÛÀÎ Minix¸¦ ±¸ÀÔÇß´Ù. ±×´Â ±×°ÍÀ» È°¿ëÇÏ¿© ¸®´ª½º¶ó ºÎ¸£´Â ÀڽŸ¸ÀÇ ¸ÖƼŽºÅ· ½Ã½ºÅÛÀ» °³¹ßÇÏ¿´´Ù. 1991³â 9¿ù ±×´Â ÀÎÅÍ³Ý »óÀÇ Minix »ç¿ëÀڵ鿡°Ô E-¸ÞÀÏÀ» ÅëÇØ Ã¹¹ø° ÇÁ·ÎÅäŸÀÔ(Prototype)À» ¹ßÇ¥Çß´Ù. ÀÌ°ÍÀÌ ¸®´ª½º ÇÁ·ÎÁ§Æ®ÀÇ ±â¿øÀÌ´Ù. ±×¶§ºÎÅÍ ¸¹Àº ÇÁ·Î±×·¡¸ÓµéÀÌ ¸®´ª½º¸¦ Áö¿øÇϱ⠽ÃÀÛÇß´Ù. ±×µéÀº µð¹ÙÀ̽º µå¶óÀ̹ö¸¦ Ãß°¡ÇÏ°í, ÀÀ¿ëÇÁ·Î±×·¥À» °³¹ßÇÏ°í POSIX¸¦ µû¸£´Â °ÍÀ» ¸ñÇ¥·Î Çß´Ù. ¿À´Ã³¯ ¸®´ª½º´Â ¸Å¿ì °­·ÂÇØÁ³Áö¸¸ °¡Àå Å« ÀåÁ¡Àº °øÂ¥(FREE)¶ó´Â Á¡ÀÌ´Ù. ´Ù¸¥ Ç÷§ÆûÀ¸·Î ¸®´ª½º¸¦ À̽ÄÇÏ´Â ÀÛ¾÷ÀÌ ÁøÇàÁßÀÌ´Ù. == ¸®´ª½º Ä¿³Î (The Linux Kernel) == ¸®´ª½ºÀÇ ±âº»Àº Ä¿³ÎÀÌ´Ù. ¸ðµç ¶óÀ̺귯¸®¸¦ ¹Ù²ã¹ö¸®´õ¶óµµ, ¸®´ª½º Ä¿³ÎÀÌ ³²¾ÆÀÖ´Â ÇÑ ¸®´ª½ºÀÌ´Ù. Ä¿³ÎÀº µð¹ÙÀ̽º µå¶óÀ̹ö, ¸Þ¸ð¸® °ü¸®, ÇÁ·Î¼¼½º °ü¸®¿Í Åë½Å °ü¸®¸¦ Æ÷ÇÔÇÑ´Ù. Ä¿³Î ÇØÄ¿µéÀº ¶§¶§·Î ÇÁ·Î±×·¡¹ÖÀ» ½±°Ôµµ ¾î·Æ°Ôµµ ¸¸µå´Â POSIX °¡À̵å¶óÀÎÀ» µû¸¥´Ù. ´ç½ÅÀÇ ÇÁ·Î±×·¥ÀÌ »õ·Î¿î ¸®´ª½º Ä¿³Î À§¿¡¼­ ´Ù¸£°Ô µ¿ÀÛÇÑ´Ù¸é, º¯È­´Â °ð »õ·Î¿î POSIX °¡À̵å¶óÀÎÀÌ ±¸ÇöµÇ¾úÀ» È®·üÀÌ Å©´Ù. ¸®´ª½º Ä¿³Î¿¡ ´ëÇÑ ÇÁ·Î±×·¡¹Ö Á¤º¸¸¦ ¿øÇÑ´Ù¸é, ¸®´ª½º Ä¿³Î ÇØÄ¿¸¦ À§ÇÑ °¡À̵å(The Linux Kernel Hacker's Guide)¸¦ Àоî¶ó. == ¸®´ª½º libc ÆÐÅ°Áö (The Linux libc Package) == libc: ISO 8859.1, , YP ÇÔ¼öµé, crypt ÇÔ¼öµé, ±âº»ÀûÀÎ Shadow ·çƾµé (±âº»ÀûÀ¸·Î´Â Æ÷ÇÔµÇÁö ¾ÊÀ½), ... libcompat¿¡ Àִ ȣȯ¼ºÀ» À§ÇÑ ±âÁ¸ÀÇ ·çƾµé (±âº»ÀûÀ¸·Î ¼öÇàµÇÁö ¾ÊÀ½),¿µ¾î,ºÒ¾î ¶Ç´Â µ¶¾î ¿¡·¯ ¸Þ¼¼Áöµé, libcourses¿¡ ÀÖ´Â bsd 4.4 lite¿Í ȣȯ¼º ÀÖ´Â È­¸é Çڵ鸵 ·çƾµé, libbsd¿¡ ÀÖ´Â bsd¿Í ȣȯµÇ´Â ·çƾµé, libtermcap¿¡ ÀÖ´Â È­¸é Çڵ鸵 ·çƾµé, libdbm¿¡ ÀÖ´Â µ¥ÀÌŸº£À̽º °ü¸® ·çƾµé, libm¿¡ ÀÖ´Â ¼öÇаè»ê ·çƾµé, crt0.o???¿¡ ÀÖ´Â ÇÁ·Î±×·¥ ½ÇÇàÀ» À§ÇÑ Ç׸ñ, libieee???¿¡ ÀÖ´Â ¹ÙÀÌÆ® sex Á¤º¸ (¿ì½º¿î ???¸¦ ´ë½ÅÇÒ Á¤º¸¸¦ º¸³»ÁÖ¼¼¿ä.), libgmon¿¡ ÀÖ´Â »ç¿ëÀÚ °ø°£ ÇÁ·ÎÆÄÀϸµ(Profiling). ¸®´ª½º libc °³¹ßÀÚµé Áß ´©±º°¡°¡ ÀÌ ÀåÀ» ½á Áֱ⸦ ¹Ù¶ø´Ï´Ù. Áö±Ý ³»°¡ ¸»ÇÒ ¼ö ÀÖ´Â °ÍÀº ½ÇÇàÇÒ ¼ö ÀÖ´Â ÇüÅÂÀÎ a.outÀÌ °øÀ¯ ¶óÀ̺귯¸® ¸¸µé±âÀÇ º¯È­¸¦ ÀǹÌÇÏ´Â elf(executable and linkable format)À¸·Î ¹Ù²ð °ÍÀ̶ó´Â °Í»ÓÀÌ´Ù. ÇöÀç´Â µÎ ÇüÅÂ(a.out°ú elf)°¡ ¸ðµÎ Áö¿øµÈ´Ù. crt0.o°°Àº ¸î¸îÀº Ưº°ÇÑ ¿¹¿ÜÀûÀÎ ÀúÀÛ±ÇÀÇ ¿µÇâÀ» ¹Þ±âµµ ÇÏÁö¸¸, ¸®´ª½º libc ÆÐÅ°ÁöÀÇ ´ëºÎºÐÀº ¶óÀ̺귯¸® GNU Public ¶óÀ̼¾½º(License)ÀÇ ¿µÇâÀ» ¹Þ´Â´Ù. »ó¾÷ÀûÀÎ ÀÌÁø ¹èÆ÷º»Àº Á¤Àû ¸µÅ©¿¡ ÀÇÇÑ ½ÇÇà¿¡ Á¦¾àÀÌ ÀÖ´Ù. µ¿Àû ¸µÅ©¿¡ ÀÇÇÑ ½ÇÇàÀº Ưº°È÷ ¿¹¿ÜÀÌ°í FSFÀÇ Richard StallmanÀº ¾Æ·¡¿Í °°ÀÌ ¸»Çß´Ù. ''Section 5¿¡ µû¶ó ½ÇÇà½ÃÅ°´Âµ¥ ¾Æ¹«·± Á¦¾àÀÌ ¾øÀÌ ¸¸µé¾îÁø ¿ÀºêÁ§Æ® ÆÄÀÏÀÌ Á¦°øµÇ´Â ¶óÀ̺귯¸®¸¦ ÷ºÎÇÏÁö ¾Ê´Â µ¿Àû ¸µÅ© ½ÇÇàÆÄÀÏÀÇ ¹èÆ÷´Â ¸í¹éÈ÷ Çã¿ëµÇ¾î¾ß ÇÑ´Ù°í º»´Ù. ±×·¡¼­ ³ª´Â Áö±Ý ±×°ÍÀ» Çã¿ëÇϵµ·Ï °áÁ¤ÇÒ °ÍÀÌ´Ù. ½ÇÁ¦ÀûÀÎ LGPLÀÇ º¸¿ÏÀº ³»°¡ »õ¹öÀüÀ» ¸¸µé°í È®ÀÎÇÒ ¶§±îÁö ±â´Ù·Á¾ß¸¸ ÇÒ °ÍÀÌ´Ù.'' == ½Ã½ºÅÛ È£Ãâ (System Calls) == ½Ã½ºÅÛ È£ÃâÀº ÀϹÝÀûÀ¸·Î ¿î¿µÃ¼Á¦(Ä¿³Î)°¡ Çϵå¿þ¾î/½Ã½ºÅÛ¿¡ ÁöÁ¤µÈ ¶Ç´Â Ư±ÇÀÌ ÀÖ¾î¾ß ÇÏ´Â µ¿ÀÛµéÀ» ¼öÇàÅä·Ï ¿äûÇÏ´Â °ÍÀÌ´Ù. ¸®´ª½º 1.2 ¿¡¼­´Â 140°³ÀÇ ½Ã½ºÅÛ È£ÃâµéÀÌ Á¤ÀǵǾî ÀÖ´Ù. close()¿Í °°Àº ½Ã½ºÅÛ È£ÃâÀº ¸®´ª½º libc¿¡ ±¸ÇöµÇ¾î ÀÖ´Ù. ÀÌ ±¸ÇöÀº Á¾Á¾ °á±¹¿¡´Â syscall()¸¦ È£ÃâÇÏ´Â ¸ÅÅ©·ÎÀÇ È£ÃâÀ» Æ÷ÇÔÇÑ´Ù. syscall()¿¡ ³Ñ°ÜÁö´Â ÆĶó¹ÌÅÍ´Â ÇÊ¿äÇÑ ¾Æ±Ô¸ÕÆ®¿¡ ÀÇÇØ ÃßÀûµÇ´Â ½Ã½ºÅÛ È£Ãâ ¹øÈ£ÀÌ´Ù. ½ÇÁ¦ÀÇ ½Ã½ºÅÛ È£Ãâ ¹øÈ£µéÀº ÀÌ »õ·Î¿î libc¿¡ ÀÇÇØ ¾÷µ¥ÀÌÆ®µÇ´Â µ¿¾È ¿¡¼­ ãÀ» ¼ö ÀÖ´Ù. libc¸¦ ±Ù°£À» µÎÁö¾Ê´Â »õ·Î¿î È£ÃâÀÌ ³ªÅ¸³ªÁö ¾Ê´Â ÇÑ syscall()¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¸é, ¾Æ·¡¿Í °°ÀÌ syscall()¸¦ »ç¿ëÇÏ¿© ÆÄÀÏÀ» ´ÝÀ» ¼ö ÀÖ´Ù.(±ÇÀåÇÏÁö ¾ÊÀ½) : {{{#!vim c #include extern int syscall(int, ...); int my_close(int filedescriptor) { return syscall(SYS_close, filedescriptor); } }}} i386 ±¸Á¶¿¡¼­´Â Çϵå¿þ¾î ·¹Áö½ºÅÍÀÇ °¹¼ö¶§¹®¿¡ ½Ã½ºÅÛ È£Ãâ ¹øÈ£ÀÌ¿Ü¿¡ 5°³ÀÇ ¾Æ±Ô¸ÕÆ®·Î ½Ã½ºÅÛ È£ÃâÀÌ Á¦ÇѵȴÙ. ¶Ç ´Ù¸¥ ±¸Á¶À§¿¡¼­ ¸®´ª½º¸¦ »ç¿ëÇÑ´Ù¸é _syscall ¸ÅÅ©·Î¸¦ À§ÇØ Çϵå¿þ¾î°¡ ¾ó¸¶³ª ¸¹Àº ¾Æ±Ô¸ÕÆ®¸¦ Áö¿øÇÏ´ÂÁö ¶Ç´Â ¾ó¸¶³ª ¸¹Àº °³¹ßÀÚÀÇ ¼±ÅÃÀÌ Áö¿øµÇ´ÂÁö¸¦ ¾Ë¾Æ º¸±âÀ§ÇØ ¸¦ üũÇÒ ¼ö ÀÖ´Ù. ÀÌ·¯ÇÑ _syscall ¸ÅÅ©·ÎµéÀº syscall() ´ë½Å¿¡ »ç¿ëµÉ ¼ö ÀÖÁö¸¸, ÀÌ·¯ÇÑ ¸ÅÅ©·Î´Â ¶óÀ̺귯¸®¿¡ ÀÌ¹Ì Á¸ÀçÇÒ·±Áö ¸ð¸£´Â Full FunctionÀ¸·Î È®ÀåµÇ¹Ç·Î ÃßõÇÒ¸¸ÇÏÁö ¸øÇÏ´Ù. {{{#!vim c #include _syscall1(int, close, int, filedescriptor); }}} _syscall1 ¸ÅÅ©·Î´Â close() ÇÔ¼ö¿Í °°Àº ¸ð½ÀÀ¸·Î È®ÀåµÈ´Ù. ±×·¯¹Ç·Î libc ¾È¿¡ close()¸¦ ÇÑ,µÎ¹ø ±×¸®°í ÇÁ·Î±×·¥ ¾È¿¡ Çѹø °¡Áø´Ù. ½Ã½ºÅÛ È£ÃâÀÌ ½ÇÆÐÇϸé syscall() À̳ª _syscall ¸ÅÅ©·ÎÀÇ ¹Ýȯ°ªÀº -1ÀÌ°í ¼º°øÇϸé 0 À̳ª 0º¸´Ù Å«°ªÀ» °®´Â´Ù. ½Ã½ºÅÛ È£ÃâÀÌ ½ÇÆÐÇß´Ù¸é ¹«½¼ ÀÏÀÌ ÀϾ´ÂÁö ¾Ë±âÀ§ÇØ Àü¿ªº¯¼öÀÎ errno¸¦ »ìÆìºÁ¶ó. BSD¿Í SYS V¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖ´Â ´ÙÀ½ÀÇ ½Ã½ºÅÛ È£ÃâµéÀº ¸®´ª½º¿¡¼­ »ç¿ëÇÒ ¼ö ¾ø´Ù. : audit(),auditon(),auditsvc(),fchroot(),getauid(),getdents(),getmsg(),mincore(), poll(),putmsg(),setaudit(),setauid(). == \"½ºÀ§½º ±º¿ë Ä®\"°°Àº ioctl (The \"swiss army knife\" ioctl) == ioctlÀº input/output controlÀ» ÀǹÌÇϸç ÆÄÀϵð½ºÅ©¸³ÅÍ(filedescriptor)¸¦ °¡Áö°í ij¸¯ÅÍ µð¹ÙÀ̽º(character device)¸¦ Á¶Á¾Çϴµ¥ »ç¿ëµÈ´Ù. ioctlÀÇ ÇüÅ´ ioctl(unsigned int fd, unsigned intrequest, unsigned long argument)ÀÌ´Ù. ¿¡·¯¸¦ ¸¸³ª¸é ¹Ýȯ°ªÀº -1ÀÌ°í ´Ù¸¥ ½Ã½ºÅÛ È£Ãâ°ú °°ÀÌ ¿äûÀÌ ¼º°øÇϸé 0º¸´Ù Å©°Å³ª °°Àº °ªÀ» °®´Â´Ù. Ä¿³ÎÀº Ư¼ö ÆÄÀÏ(special file)À̳ª ÀÏ¹Ý ÆÄÀϵé(regular files)°ú ±¸ºÐµÈ´Ù. Ư¼ö ÆÄÀÏ(special file)Àº ÁÖ·Î /dev³ª /proc µð·ºÅ丮¿¡¼­ ãÀ» ¼ö ÀÖ´Ù. ÀÌ ÆÄÀϵéÀº µå¶óÀ̹ö¿ÍÀÇ ÀÎÅÍÆäÀ̽º¸¦ ¼û±â°í ÀÖ°í ÅؽºÆ®³ª ÀÌÁø µ¥ÀÌŸ¸¦ Æ÷ÇÔÇÏ´Â ½ÇÁ¦(ÀϹÝ) ÆÄÀÏÀÌ ¾Æ´Ï¶ó´Â Á¡¿¡¼­ ÀÏ¹Ý ÆÄÀÏ(regular file)°ú ´Ù¸£´Ù. ÀÌ·¯ÇÑ Á¡Àº À¯´Ð½ºÀÇ Ã¶ÇÐÀÌ°í ¸ðµç ÆÄÀÏ¿¡ ´ëÇØ Á¤»óÀûÀ¸·Î Àбâ/¾²±â µ¿ÀÛÀÇ »ç¿ëÀ» Çã¶ôÇÑ´Ù. ±×·¯³ª Ư¼ö ÆÄÀÏÀ̳ª ÀÏ¹Ý ÆÄÀÏÀ» °¡Áö°í ±× ÀÌ»óÀÇ ÀÏÀ» ÇÏ°íÀÚ ÇÑ´Ù¸é ioctl¸¦ °¡Áö°í ÇÒ ¼ö ÀÖ´Ù. ÀÏ¹Ý ÆÄÀϺ¸´Ù´Â Ư¼ö ÆÄÀÏ¿¡ ´ëÇØ ioctlÀÌ Á¾Á¾ ´õ ¸¹ÀÌ ÇÊ¿äÇÒÅ×Áö¸¸ ÀÏ¹Ý ÆÄÀÏ¿¡ ´ëÇؼ­µµ ioctlÀÇ »ç¿ëÀÌ °¡´ÉÇÏ´Ù. == ¸®´ª½º ÇÁ·Î¼¼½º°£ÀÇ Åë½Å (Linux Interprocess Communications) == '''Ãß»óÀû °³³ä:''' IPC(interprocess communication facilities)¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ³»¿ëÀº ¸®´ª½º ¿î¿µÃ¼Á¦¿¡ ±â¼ú µÇ¾î ÀÖ´Ù. === ¼Ò°³ (Introduction) === ¸®´ª½º IPC(Inter-process communication)Àº ¿©·¯ ÇÁ·Î¼¼½ºµéÀÌ ´Ù¸¥ ÇÁ·Î¼¼½º¿Í Åë½ÅÇÒ ¼ö ÀÖ´Â ¹æ¹ýÀ» Á¦°øÇÑ´Ù. ¸®´ª½º C ÇÁ·Î±×·¡¸ÓµéÀÌ ÀÌ¿ëÇÒ ¼ö ÀÖ´Â IPC ¹æ¹ý¿¡´Â ¾Æ·¡¿Í °°Àº ¸î°¡Áö°¡ ÀÖ´Ù. * ¹ÝÀÌÁß À¯´Ð½º ÆÄÀÌÇÁ (Half-duplex UNIX pipes) * FIFOs (named pipes) * SYS V ½ºÅ¸ÀÏÀÇ ¸Þ¼¼Áö Å¥ (SYS V style message queues) * SYS V ½ºÅ¸ÀÏÀÇ ¼¼¸¶ÆÛ ÁýÇÕ (SYS V style semaphore sets) * SYS V ½ºÅ¸ÀÏÀÇ °øÀ¯ ¸Þ¸ð¸® ¼¼±×¸àÆ® (SYS V style shared memory segments) * ³×Æ®¿öÅ· ¼ÒÄÏ (¹öŬ¸® ½ºÅ¸ÀÏ) (Networking sockets (Berkeley style)) : ¿©±â¼­´Â ´Ù·çÁö ¾ÊÀ½ * ÀüÀÌÁß ÆÄÀÌÇÁ (Full-duplex pipes (STREAMS pipes) : ¿©±â¼­´Â ´Ù·çÁö ¾ÊÀ½ ÀÌ·¯ÇÑ ¹æ¹ýµéÀÌ È¿°úÀûÀ¸·Î »ç¿ëµÉ ¶§, ¸®´ª½º¸¦ Æ÷ÇÔÇÑ ¸ðµç À¯´Ð½º ½Ã½ºÅÛ¿¡¼­ÀÇ Å¬¶óÀ̾ðÆ®/¼­¹ö °³¹ßÀ» À§ÇÑ °ß°íÇÑ ÇÁ·¹ÀÓ¿÷Å©(framework)¸¦ Á¦°øÇÑ´Ù. === ¹ÝÀÌÁß À¯´Ð½º ÆÄÀÌÇÁ (Half-duplex UNIX Pipes) === ==== ±âº» °³³ä (Basic Concepts) ==== °£´ÜÈ÷ ¸»Çؼ­, ÆÄÀÌÇÁ(Pipe)´Â ÇÑ ÇÁ·Î¼¼½ºÀÇ Ç¥ÁØ Ãâ·Â(Standard output)À» ´Ù¸¥ ÇÁ·Î¼¼½ºÀÇ Ç¥ÁØ ÀÔ·Â(Standard input)À¸·Î ¿¬°áÇÏ´Â ¹æ¹ýÀÌ´Ù. ÆÄÀÌÇÁ´Â IPCÅø Áß °¡Àå ¿À·¡µÈ °ÍÀ¸·Î À¯´Ð½º ¿î¿µÃ¼Á¦ÀÇ Ãʱ⠴ܰèºÎÅÍ »ç¿ëµÇ¾î ¿Ô´Ù. ÆÄÀÌÇÁ´Â ÇÁ·Î¼¼½º°£ÀÇ ´Ü¹æÇâ(¹ÝÀÌÁß,half-duplex) Åë½ÅÀÇ ÇÑ ¹æ¹ýÀ» Á¦°øÇÑ´Ù. ÀÌ·¯ÇÑ Æ¯Â¡Àº À¯´Ð½º ¸í·É¾î ¶óÀÎ(À¯´Ð½º ½©)¿¡¼­ Á¶Â÷ Æø³Ð°Ô »ç¿ëµÈ´Ù. ls | sort | lp À§ÀÇ ¿¹´Â lsÀÇ Ãâ·ÂÀ» sortÀÇ ÀÔ·ÂÀ¸·Î ÇÏ°í sortÀÇ Ãâ·ÂÀ» lpÀÇ ÀÔ·ÂÀ¸·Î »ç¿ëÇϱâ À§ÇØ ÆÄÀÌÇÁ(pipe)¸¦ ÀÌ¿ëÇÏ¿´´Ù. ÀÚ·á´Â ÆÄÀÌÇÁ¶óÀÎÀ» ÅëÇØ ¿ÞÂÊ¿¡¼­ ¿À¸¥ÂÊÀ¸·Î À̵¿ÇϵíÀÌ, ¹ÝÀÌÁß ÆÄÀÌÇÁ¸¦ ÅëÇØ ¿òÁ÷ÀδÙ. ¿ì¸®µéÀÌ ½© ½ºÅ©¸³Æ® ÇÁ·Î±×·¡¹Ö¿¡¼­ ÆÄÀÌÇÁ¸¦ ¾ÆÁÖ ¼¼½ÉÇÏ°Ô »ç¿ëÇÑ´ÙÇصµ, Ä¿³Î ·¹º§¿¡¼­ ÀϾ´Â ÀÏ¿¡ ´ëÇؼ­´Â »ý°¢ÇÏÁö ¾Ê°í »ç¿ëÇÑ´Ù. ÇÁ·Î¼¼½º°¡ ÆÄÀÌÇÁ¸¦ ¸¸µé ¶§, Ä¿³ÎÀº ÆÄÀÌÇÁ¿¡ ÀÇÇØ »ç¿ëµÉ µÎ°³ÀÇ ÆÄÀÏ ½Äº°ÀÚ(descriptor)¸¦ ÁغñÇÑ´Ù. ÇÑ°³ÀÇ ½Äº°ÀÚ(descriptor)´Â ÆÄÀÌÇÁ(Write)ÀÇ ÀÔ·Â Åë·Î·Î »ç¿ëµÇ°í ´Ù¸¥ Çϳª´Â ÆÄÀÌÇÁ(Read)·Î ºÎÅÍ ÀڷḦ ¾ò´Âµ¥ »ç¿ëµÈ´Ù. ÀÌ·± Á¡¿¡¼­ »ý¼ºÇÏ´Â ÇÁ·Î¼¼½º´Â ÀÚ±âÀڽŰúÀÇ Åë½Å¿¡¸¸ ÆÄÀÌÇÁ¸¦ »ç¿ëÇÔÀ¸·Î ÆÄÀÌÇÁ´Â °ÅÀÇ ½ÇÁúÀûÀ¸·Î »ç¿ëµÇÁö ¾Ê´Â´Ù. ÆÄÀÌÇÁ°¡ ¸¸µé¾îÁø ÀÌÈÄÀÇ ÇÁ·Î¼¼½º¿Í Ä¿³ÎÀÇ °³³äÀÛ¿ë¿¡ ÁÖÀÇÇ϶ó. - ¾Ö¼®ÇÏ°Ôµµ ¿ø¹®¿¡¼­ ´ÙÀ̾î±×·¥ ±×¸²ÀÌ ºüÁ®ÀÖÀ½ À§ÀÇ ´ÙÀ̾î±×·¥À¸·Î ºÎÅÍ ½Äº°ÀÚµéÀÌ ¼­·Î ¾î¶»°Ô ¿¬°áµÇ´ÂÁö ½±°Ô ¾Ë ¼ö ÀÖ´Ù. ÇÁ·Î¼¼½º°¡ ÆÄÀÌÇÁ(fd0)¸¦ ÅëÇØ ÀڷḦ º¸³½´Ù¸é, fd1·Î ºÎÅÍ ÀڷḦ ¾òÀ» ¼ö (ÀÐÀ» ¼ö) ÀÖ´Â ´É·ÂÀ» °¡Áö°í ÀÖ´Ù. ±×·¸Áö¸¸ À§ÀÇ ±ØÈ÷ °£´ÜÇÑ ±×¸²ÀÇ ½ÇÀç¹°Àº ¸Å¿ì Å©´Ù. ÆÄÀÌÇÁ°¡ óÀ½¿¡ ÇÁ·Î¼¼½º¿Í ÀÚ½ÅÀ» ¿¬°áÇÏ´Â µ¿¾È, ÆÄÀÌÇÁ¸¦ ÅëÇØ ¿©Çà ÁßÀÎ ÀÚ·á´Â Ä¿³ÎÀ» ÅëÇØ ¿òÁ÷ÀδÙ. ƯÈ÷ ¸®´ª½º¿¡¼­ ÆÄÀÌÇÁ´Â ½ÇÁ¦·Î ³»ºÎÀûÀ¸·Î À¯È¿ÇÑ inode¸¦ °¡Áö°í ÀÖÀ½À» ÀǹÌÇÑ´Ù. ¹°·Ð, ÀÌ inode´Â Ä¿³Î¾È¿¡ Á¸ÀçÇÏ°í ¹°¸®ÀûÀÎ ÆÄÀÏ ½Ã½ºÅÛ¿¡´Â ¾Æ¹«·± ¿µÇâÀ» ³¢Ä¡Áö ¾Ê´Â´Ù. ÀÌ·¯ÇÑ Æ¯Â¡Àº ¿ì¸®°¡ ¼öµ¿ I/O ¹®(handy I/O doors)À» ¿­ ¼ö ÀÖ°Ô ÇÑ´Ù. ÀÌ·¯ÇÑ Á¡¿¡¼­ ÆÄÀÌÇÁ´Â ¸í¹éÈ÷ ¾µ¸ð¾ø´Ù. °á±¹, ¿ì¸®°¡ ¿ÀÁ÷ ¿ì¸® Àڽſ¡°Ô À̾߱âÇÏ°íÀÚ ÇÑ´Ù¸é ¿Ö ÆÄÀÌÇÁ »ý¼ºÀÇ ¾î·Á¿òÀ» °¡Áö°í °¡¾ß¸¸ Çϴ°¡? »ý¼ºÇÏ´Â(creating) ÇÁ·Î¼¼½º´Â ÀüÅëÀûÀ¸·Î ÀÚ½Ä ÇÁ·Î¼¼½º(child process)¸¦ »ý¼º(fork)ÇÑ´Ù. ÀÚ½Ä ÇÁ·Î¼¼½º´Â ºÎ¸ð·Î ºÎÅÍ ¿­·ÁÁø ÆÄÀÏ ½Äº°ÀÚµµ »ó¼Ó¹Þ¾ÒÀ¸¹Ç·Î ¿ì¸®´Â ºÎ¸ð¿Í Àڽİ£ÀÇ ¸ÖƼÇÁ·Î¼¼½º Åë½ÅÀ» À§ÇÑ ±âÃʸ¦ °¡Áö°í ÀÖ´Ù. ¿ì¸®ÀÇ °£´ÜÇÑ ±×¸² ¼öÁ¤º»¿¡ ÁÖÀÇÇ϶ó. [http://wiki.kldp.org/pds/6%5F2%5F1%5F2.gif http://wiki.kldp.org/pds/6%5F2%5F1%5F2.gif ] À§¿Í °°ÀÌ ¿ì¸®´Â µÎ ÇÁ·Î¼¼½º°¡ ÆÄÀÌÇÁ ¶óÀÎÀ» ±¸¼ºÇÏ´Â ÆÄÀÏ ½Äº°ÀÚ¿¡ Á¢±ÙÇÒ ¼ö ÀÖÀ½À» º¼ ¼ö ÀÖ´Ù. À̹ø¿¡´Â Áß¿äÇÑ °áÁ¤À» ³»·Á¾ß ÇÑ´Ù. ¾î¶² ¹æÇâÀ¸·Î ÀÚ·á°¡ À̵¿Çϱ⸦ ¿øÇϴ°¡? ÀÚ½Ä ÇÁ·Î¼¼½º°¡ ºÎ¸ð¿¡°Ô Á¤º¸¸¦ º¸³¾ °ÍÀΰ¡ ¾Æ´Ï¸é ±× ¹Ý´ëÀΰ¡? µÎ ÇÁ·Î¼¼½º´Â ÀÌ·¯ÇÑ ¹®Á¦¿¡ ´ëÇØ »óÈ£ µ¿ÀÇÇÏ°í ÀÖ°í °ü°èµÇ¾î ÀÖÁö ¾ÊÀº ÆÄÀÌÇÁÀÇ ³¡Àº ´Ý´Â´Ù. Åä·ÐÀÇ ¸ñÀûÀ» À§ÇØ, ÀÚ½Ä ÇÁ·Î¼¼½º°¡ ¾î¶² ÀÛ¾÷À» ¼öÇàÇÏ°í ÆÄÀÌÇÁ¸¦ ÅëÇØ ºÎ¸ð¿¡°Ô Á¤º¸¸¦ ÀüÇÏ´ÂÁö¸¦ »ìÆ캸ÀÚ. ¿ì¸®ÀÇ »õ·Ó°Ô °í¾ÈµÈ ±×¸²Àº ´ÙÀ½°ú °°ÀÌ ³ªÅ¸³­´Ù.: [http://wiki.kldp.org/pds/6%5F2%5F1%5F3.gif http://wiki.kldp.org/pds/6%5F2%5F1%5F3.gif ] ÇöÀç ÆÄÀÌÇÁ¶óÀÎÀÇ ±¸¼ºÀº ¿Ïº®ÇÏ´Ù! ³²¾ÆÀÖ´Â ÀÏÀº ÆÄÀÌÇÁÀÇ »ç¿ë»ÓÀÌ´Ù. ÆÄÀÌÇÁ¿¡ Á÷Á¢ÀûÀ¸·Î Á¢±ÙÇϱâ À§ÇØ, ÇÏÀ§ ·¹º§ÀÇ ÆÄÀÏ I/O¸¦ À§ÇØ »ç¿ëµÇ´Â °°Àº ±â´ÉÀÇ ½Ã½ºÅÛ È£ÃâÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. (ÆÄÀÌÇÁ°¡ ½ÇÁ¦ ³»ºÎÀûÀ¸·Î À¯È¿ÇÑ inode·Î Ç¥ÇöµÊÀ» ±â¾ïÇ϶ó) ÆÄÀÌÇÁ·Î ÀڷḦ º¸³»±â À§ÇØ, ¿ì¸®´Â write() ½Ã½ºÅÛ È£ÃâÀ» »ç¿ëÇÏ°í ÆÄÀÌÇÁ·Î ºÎÅÍ ÀڷḦ Á¶È¸Çϱâ À§ÇØ read()¶ó´Â ½Ã½ºÅÛ È£ÃâÀ» »ç¿ëÇÑ´Ù. ÇÏÀ§ ·¹º§ÀÇ ÆÄÀÏ I/O ½Ã½ºÅÛ È£ÃâÀº ÆÄÀÏ ½Äº°ÀÚ¸¦ °¡Áö°í ÀÛ¾÷ÇÔÀ» ±â¾ïÇ϶ó! ¾î·µç, ÆÄÀÌÇÁ¿¡¼­ ½Äº°ÀÚ¸¦ °¡Áö°í ÀÛ¾÷ÇÏÁö ¾Ê´Â lseek()¿Í °°Àº ½Ã½ºÅÛ È£ÃâµéÀ» ±â¾ïÇ϶ó. ==== C·Î ÆÄÀÌÇÁ ¸¸µé±â (Creating Pipes in C) ==== C ÇÁ·Î±×·¡¹Ö ¾ð¾î·Î ÆÄÀÌÇÁ¶óÀÎÀ» ¸¸µå´Â °ÍÀº °£´ÜÇÑ ½© ¿¹Á¦º¸´Ù´Â ¸¹Àº °ÍÀ» Æ÷ÇÔÇÑ´Ù. C·Î °£´ÜÇÑ ÆÄÀÌÇÁ¸¦ ¸¸µé±â À§ÇØ pipe() ½Ã½ºÅÛ È£ÃâÀ» »ç¿ëÇÑ´Ù. ÀÌ°ÍÀº µÎ Á¤¼öÀÇ ¹è¿­ÀÎ ÇÑ°³ÀÇ ¾Æ±Ô¸ÕÆ®(argument)¸¦ °¡Áö¸ç, ¼º°øÇÏ¸é ¹è¿­Àº ÆÄÀÌÇÁ ¶óÀÎÀ» À§ÇØ »ç¿ëµÇ´Â »õ·Î¿î µÎ°³ÀÇ ÆÄÀÏ ½Äº°ÀÚ¸¦ °®´Â´Ù. ÆÄÀÌÇÁ¸¦ ¸¸µé°í ³­ ÈÄ, ÇÁ·Î¼¼½º´Â ÀüÅëÀûÀ¸·Î »õ·Î¿î ÇÁ·Î¼¼½º¸¦ ³º´Â´Ù. (ÀÚ½ÄÀº ¿­·ÁÁø ÆÄÀÏ ½Äº°ÀÚ¸¦ »ó¼Ó¹Þ´Â´Ù´Â °ÍÀ» ±â¾ïÇ϶ó) {{{ SYSTEM CALL: pipe(); PROTOTYPE: int pipe(int fd[2]); RETURNS: ¼º°ø½Ã 0 -1 on error: errno = EMFILE (ÀÚÀ¯·Î¿î ½Äº°ÀÚ°¡ ¾ø´Ù) EMFILE (½Ã½ºÅÛ ÆÄÀÏ Å×À̺íÀÌ ´Ù á´Ù) EFAULT (fd ¹è¿­ÀÌ À¯È¿ÇÏÁö ¾Ê´Ù) NOTES: fd[0]´Â Àб⸦ À§ÇØ ÁغñµÇ°í, fd[1]Àº ¾²±â¸¦ À§ÇØ ÁغñµÈ´Ù. }}} ¹è¿­ÀÇ Ã¹¹ø° Á¤¼ö(element 0)´Â Àб⸦ À§ÇØ ÁغñµÇ°í ¿­·ÁÁö´Â ¹Ý¸é, µÎ¹ø° Á¤¼ö(element 1)´Â ¾²±â¸¦ À§ÇØ ÁغñµÇ°í ¿­·ÁÁø´Ù. ½Ã°¢ÀûÀ¸·Î ¸»Çϸé, fd1ÀÇ Ãâ·ÂÀº fd0¸¦ À§ÇÑ ÀÔ·ÂÀÌ µÈ´Ù. ÆÄÀÌÇÁ¸¦ ÅëÇØ À̵¿ÇÏ´Â ¸ðµç ÀÚ·á´Â Ä¿³ÎÀ» ÅëÇØ À̵¿ÇÔÀ» ´Ù½Ã ¸»ÇصдÙ. {{{#!vim c #include #include #include main() { int fd[2]; pipe(fd); . . } }}} C¿¡¼­ ¹è¿­ÀÇ À̸§Àº ù¹ø° ¸â¹öÀÇ Æ÷ÀÎÅÍÀÓÀ» ±â¾ïÇ϶ó. À§¿¡¼­, fd´Â &fd[0]¿Í °°´Ù. ÆÄÀÌÇÁ ¶óÀÎÀ» ¸¸µé°í ³­ ÈÄ, »õ·Î¿î ÀÚ½Ä ÇÁ·Î¼¼½º¸¦ »ý¼º(fork)ÇÑ´Ù.: {{{#!vim c #include #include #include main() { int fd[2]; pipe(fd); if((childpid = fork()) == -1) { perror("fork"); exit(1); } . . } }}} ºÎ¸ð°¡ ÀÚ½ÄÀ¸·Î ºÎÅÍ ÀڷḦ Á¶È¸Çϱ⸦ ¿øÇÑ´Ù¸é, fd1¸¦ ´Ý¾Æ¾ß ÇÏ°í ÀÚ½ÄÀº fd0¸¦ ´Ý¾Æ¾ß ÇÑ´Ù. ºÎ¸ð°¡ ÀڽĿ¡°Ô ÀڷḦ º¸³»°íÀÚ ÇÑ´Ù¸é, fd0¸¦ ´Ý¾Æ¾ß ÇÏ°í ÀÚ½ÄÀº fd1À» ´Ý¾Æ¾ß ÇÑ´Ù. ºÎ¸ð¿Í Àڽİ£¿¡ ½Äº°ÀÚ¸¦ °øÀ¯ÇÏ°í ÀÖÀ¸¹Ç·Î, °ü°èÇÏ°í ÀÖÁö ¾Ê´Â ÆÄÀÌÇÁÀÇ ³¡Àº Ç×»ó ´ÝÇôÁ®¾ß¸¸ ÇÑ´Ù. ±â¼úÀûÀÎ ÁÖÀÇ»çÇ×Àº ºÒÇÊ¿äÇÑ ÆÄÀÌÇÁÀÇ ³¡À» ¸í¹éÇÏ°Ô ´ÝÁö ¾ÊÀ¸¸é EOF´Â ¿µ¿øÈ÷ µ¹¾Æ¿ÀÁö ¾Ê´Â´Ù´Â °ÍÀÌ´Ù. {{{#!vim c #include #include #include main() { int^Ifd[2]; pid_t^Ichildpid; pipe(fd); if((childpid = fork()) == -1) { perror("fork"); exit(1); } if(childpid == 0) { /*ÀÚ½Ä ÇÁ·Î¼¼½º´Â ÆÄÀÌÇÁÀÇ ÀÔ·Â ÂÊÀ» ´Ý´Â´Ù*/ close(fd[0]); } else { /*ºÎ¸ð ÇÁ·Î¼¼½º´Â ÆÄÀÌÇÁÀÇ Ãâ·Â ÂÊÀ» ´Ý´Â´Ù*/ close(fd[1]); } . . } }}} ¾Õ¿¡¼­ ¸»Çß´ø °Íó·³, ÆÄÀÌÇÁ¶óÀÎÀ» ¸¸µç ÈÄ¿¡ ÆÄÀÏ ½Äº°ÀÚ´Â ÀÏ¹Ý ÆÄÀÏÀÇ ½Äº°ÀÚó·³ Ãë±ÞµÈ´Ù. {{{#!vim c /***************************************************************************** ¸®´ª½º ÇÁ·Î±×·¡¸Ó¸¦ À§ÇÑ °¡À̵å - 6Àå ¿¡¼­ ¹ßÃé (C)opyright 1994-1995, Scott Burkett ***************************************************************************** MODULE: pipe.c *****************************************************************************/ #include #include #include int main(void) { int fd[2], nbytes; pid_t childpid; char string[] = "Hello, world!\n"; char readbuffer[80]; pipe(fd); if((childpid = fork()) == -1) { perror("fork"); exit(1); } if(childpid == 0) { ^I^I/*ÀÚ½Ä ÇÁ·Î¼¼½º´Â ÆÄÀÌÇÁÀÇ ÀÔ·Â ÂÊÀ» ´Ý´Â´Ù*/ close(fd[0]); ^I^I/*ÆÄÀÌÇÁÀÇ Ãâ·Â ÂÊÀ¸·Î "string"À» º¸³½´Ù*/ write(fd[1], string, strlen(string)); exit(0); } else { ^I^I/*ºÎ¸ð ÇÁ·Î¼¼½º´Â ÆÄÀÌÇÁÀÇ Ãâ·Â ÂÊÀ» ´Ý´Â´Ù*/ close(fd[1]); ^I^I/*ÆÄÀÌÇÁ·Î ºÎÅÍ ¹®ÀÚ¿­À» Àд´Ù*/ nbytes = read(fd[0], readbuffer, sizeof(readbuffer)); printf("Received string: %s", readbuffer); } return(0); } }}} Á¾Á¾ ÀÚ½ÄÀÇ ½Äº°Àڴ ǥÁØ ÀÔ·Â ¶Ç´Â Ãâ·Â°ú ÁßøµÈ´Ù. ÀÚ½ÄÀº Ç¥ÁØ streamÀ» »ó¼ÓÇÏ´Â ´Ù¸¥ ÇÁ·Î±×·¥À» exec() ÇÒ ¼ö ÀÖ´Ù. dup() ½Ã½ºÅÛ È£ÃâÀ» »ìÆ캸ÀÚ.: {{{ SYSTEM CALL: dup(); PROTOTYPE: int dup( int oldfd ); RETURNS: ¼º°ø½Ã »õ·Î¿î ½Äº°ÀÚ -1 on error: errno = EBADF (oldfd°¡ À¯È¿ÇÑ ½Äº°ÀÚ°¡ ¾Æ´Ï´Ù) EBADF (newfd°¡ ¹üÀ§¸¦ ¹þ¾î³µ´Ù) EMFILE (ÇÁ·Î¼¼½º¿¡ ´ëÇØ ½Äº°ÀÚ°¡ ³Ê¹« ¸¹´Ù) NOTES: °ú°ÅÀÇ ½Äº°ÀÚ´Â ´ÝÇôÁöÁö ¾Ê´Â´Ù. µÎ°³°¡ »óÈ£ ±³È¯µÇ¾îÁú ¼ö ÀÖ´Ù. }}} °ú°ÅÀÇ ½Äº°ÀÚ¿Í »õ·Î ¸¸µé¾îÁø ½Äº°ÀÚ°¡ »óÈ£ ±³È¯µÇ¾îÁú ¼ö ÀÖ´õ¶óµµ, ÀüÅëÀûÀ¸·Î Ç¥ÁØ streamÀÇ ÇÑÂÊÀ» ´Ý´Â´Ù. dup() ½Ã½ºÅÛ È£ÃâÀº »õ·Î¿î ½Äº°ÀÚ¿¡°Ô ¾ÆÁ÷ »ç¿ëµÇÁö ¾ÊÀº °¡Àå ÀÛÀº ¹øÈ£¸¦ ºÎ¿©ÇÑ´Ù. ÁÖÀÇÇؼ­ º¸ÀÚ: {{{#!vim c . . childpid = fork(); if(childpid == 0) { ^I^I/*ÀÚ½ÄÀÇ Ç¥ÁØ ÀÔ·ÂÀ» ´Ý´Â´Ù*/ close(0); ^I^I/*ÆÄÀÌÇÁÀÇ ÀÔ·Â ÂÊÀ» Ç¥ÁØÀÔ·ÂÀ¸·Î ÇÑ´Ù*/ dup(fd[0]); execlp("sort", "sort", NULL); . } }}} ÆÄÀÏ ½Äº°ÀÚ 0ÀÌ ´ÝÈù ÈÄ, dup()¸¦ È£ÃâÇÏ¿© ÆÄÀÌÇÁÀÇ ÀÔ·Â ½Äº°ÀÚ(fd0)¸¦ Ç¥ÁØ ÀÔ·ÂÀ¸·Î º¹»çÇÑ´Ù. Á¤·Ä(sort) ÇÁ·Î±×·¥°ú ÀÚ½ÄÀÇ ÅؽºÆ® ¼¼±×¸ÕÆ®(text segment)¸¦ Áßø½ÃÅ°±â À§ÇØ execlp()ÀÇ È£ÃâÀ» »ç¿ëÇÑ´Ù. »õ·Ó°Ô execµÈ ÇÁ·Î±×·¥µéÀº ±×µéÀÇ ºÎ¸ð·Î ºÎÅÍ Ç¥ÁØ streamÀ» »ó¼Ó¹ÞÀ¸¹Ç·Î, ½ÇÁ¦·Î ÆÄÀÌÇÁÀÇ ÀÔ·Â ³¡À» Ç¥ÁØ ÀÔ·Âó·³ »ó¼Ó¹Þ´Â´Ù. ¿ø·¡ÀÇ ºÎ¸ð ÇÁ·Î¼¼½º°¡ ÆÄÀÌÇÁ·Î º¸³»·Á´Â °ÍÀº sort·Î °¡°Ô µÈ´Ù. dup2()¶ó´Â ¶Ç ´Ù¸¥ ½Ã½ºÅÛ È£ÃâÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÀÌ·¯ÇÑ Æ¯º°ÇÑ È£ÃâÀº À¯´Ð½º ¹öÀü 7·Î ºÎÅÍ ½ÃÀ۵Ǿú°í, BSD ¹öÀü¿¡¼­µµ ¼öÇàµÇ¸ç POSIX Ç¥ÁØ¿¡¼­µµ ÇÊ¿äÇÏ´Ù. {{{ SYSTEM CALL: dup2(); PROTOTYPE: int dup2( int oldfd, int newfd ); RETURNS: ¼º°ø½Ã »õ ½Äº°ÀÚ -1 on error: errno = EBADF (oldfd°¡ À¯È¿ÇÑ ½Äº°ÀÚ°¡ ¾Æ´Ï´Ù) EBADF (newfd°¡ ¹üÀ§¸¦ ¹þ¾î³µ´Ù) EMFILE (ÇÁ·Î¼¼½º¿¡ ´ëÇØ ½Äº°ÀÚ°¡ ³Ê¹« ¸¹´Ù) NOTES: °ú°ÅÀÇ ½Äº°ÀÚ´Â dup2()¿¡ ÀÇÇØ ´ÝÈù´Ù! }}} ÀÌ·± Ưº°ÇÑ È£ÃâÀ» »ç¿ëÇÏ¿© ÇÑ°³ÀÇ ½Ã½ºÅÛ È£Ãâ·Î Æ÷ÀåµÇ¾î ÀÖ´Â close ÀÛ¾÷°ú ½ÇÁ¦ ½Äº°ÀÚ º¹»ç ÀÛ¾÷À» ÇÑ´Ù. °Ô´Ù°¡, ÀÛ¾÷ÀÇ ¿øÀÚÈ­(atomic)°¡ Çã¿ëµÇ´Âµ¥ ÀÌ´Â ±âº»ÀûÀ¸·Î ½ÅÈ£ÀÇ µµÂø¿¡ ÀÇÇØ ÀÛ¾÷ÀÌ ÁߴܵÇÁö ¾ÊÀ½À» ÀǹÌÇÑ´Ù. Àüü µ¿ÀÛÀº ½ÅÈ£ÀÇ ¹ß¼ÛÀ» À§ÇØ Ä¿³Î¿¡°Ô ÅëÁ¦±ÇÀ» µ¹·ÁÁÖ±â Àü¿¡ ÀϾ´Ù. ÇÁ·Î±×·¡¸Ó´Â È£ÃâÇϱâ Àü¿¡ ¿ø·¡ÀÇ dup() ½Ã½ºÅÛ È£ÃâÀ» °¡Áö°í close() ÀÛ¾÷À» ¼öÇàÇؾ߸¸ ÇÑ´Ù. ±×°ÍÀº ±×µé »çÀÌ¿¡¼­ °æ°úµÇ´Â ÀÛÀº ½Ã°£ÀÇ ¾ç¿¡ ´ëÇÑ ´Ù¼ÒÀÇ ¾àÁ¡À» °¡Áø µÎ°³ÀÇ ½Ã½ºÅÛ È£Ãâ·Î ³¡³­´Ù. ±× ªÀº »çÀÌ¿¡ ½ÅÈ£°¡ µµÂøÇÑ´Ù¸é, ½Ãº°ÀÚÀÇ º¹»ç´Â ½ÇÆÐÇÑ´Ù. ¹°·Ð, dup2()´Â ÀÌ·¯ÇÑ ¹®Á¦¸¦ ÇØ°áÇß´Ù. »ìÆ캸ÀÚ: {{{#!vim c . . childpid = fork(); if(childpid == 0) { /* Close stdin, duplicate the input side of pipe to stdin */ dup2(0, fd[0]); execlp("sort", "sort", NULL); . . } }}} ==== ÆÄÀÌÇÁ ½¬¿î ¹æ¹ý! (pipes the Easy Way!) ==== ¾ÕÀÇ µÎ¼­¾ø´Â ±ÛµéÀÌ ÆÄÀÌÇÁ¸¦ ¸¸µé°í »ç¿ëÇÏ´Â ¸Å¿ì ¹«³­ÇÑ ¹æ¹ýó·³ º¸¿´´Ù¸é, ¶Ç ´Ù¸¥ °ÍÀÌ ÀÖ´Ù. {{{ LIBRARY FUNCTION: popen(); PROTOTYPE: FILE *popen ( char *command, char *type); RETURNS: ¼º°ø½Ã »õ·Î¿î ÆÄÀÏ ½ºÆ®¸²(stream) fork(),pipe()È£ÃâÀÌ ½ÇÆÐÇßÀ» ¶§ ³Î(NULL) NOTES: ¸í·É¾î("command")¸¦ »ç¿ëÇÏ¿© ÆÄÀÌÇÁ¸¦ ¸¸µé°í fork/exec¸¦ ¼öÇàÇÑ´Ù. }}} ÀÌ Ç¥ÁØ ¶óÀ̺귯¸® ÇÔ¼ö´Â ³»ºÎÀûÀ¸·Î pipe()¸¦ È£ÃâÇÏ¿© ¹ÝÀÌÁß ÆÄÀÌÇÁ¶óÀÎÀ» ¸¸µç´Ù. ½©¿¡¼­ ÀÚ½Ä ÇÁ·Î¼¼½º¸¦ »ý¼º(fork)ÇÏ°í, º» ½©(Bourne ahell)À» execÇÏ°í "command" ¾Æ±Ô¸ÕÆ®¸¦ ½ÇÇàÇÑ´Ù. ÀÚ·á È帧ÀÇ ¹æÇâÀº µÎ¹ø° ¾Æ¹Â¸ÕÆ®ÀÎ "type"¿¡ ÀÇÇØ °áÁ¤µÈ´Ù. "read"À̳ª "write"¿¡ ´ëÇØ "r"À̳ª "w"°¡ µÉ ¼ö ÀÖ´Ù. µÎ°¡Áö°¡ ¸ðµÎ µÉ ¼ö´Â ¾ø´Ù. ¸®´ª½º¿¡¼­, ÆÄÀÌÇÁ´Â "type"ÀÇ Ã¹¹ø° ±ÛÀÚ¿¡ ÀÇÇØ ÁöÁ¤µÈ ¸ðµå·Î ¿­·ÁÁø´Ù. µû¶ó¼­, "rw"¸¦ ³Ñ±ä´Ù¸é Àбâ("read") ¸ðµå·Î ¿­·ÁÁø´Ù. ÀÌ ¶óÀ̺귯¸® ÇÔ¼ö°¡ ´ç½ÅÀ» À§ÇØ ±î´Ù·Î¿î ÀÏÀ» ¼öÇàÇÏ´Â µ¿¾È, Áß¿äÇÑ ÈïÁ¤(tradeoff)ÀÌ ÀϾ´Ù. pipe() ½Ã½ºÅÛ È£ÃâÀ» »ç¿ëÇÏ°í fork/exec¸¦ Ãë±ÞÇÏ´Â °Í¿¡ ÀÇÇØ ´ç½ÅÀº Àá½Ã ÅëÁ¦±ÇÀ» ÀÒ¾î¹ö¸°´Ù. º» ½©ÀÌ Á÷Á¢ »ç¿ëµÇ¹Ç·Î, "command" ¾Æ±Ô¸ÕÆ® ³»¿¡¼­ ¿ÍÀϵå Ä«µå(wildcard)¸¦ Æ÷ÇÔÇÑ ½© ¸ÞŸ¹®ÀÚ È®Àå(shell metacharacter expansion)ÀÌ °¡´ÉÇÏ´Ù. popen()¿¡ ÀÇÇØ ¸¸µé¾îÁø ÆÄÀÌÇÁ´Â pclose()·Î ´Ý¾Æ¾ß¸¸ ÇÑ´Ù. popen/pclose°¡ Ç¥ÁØ ÆÄÀÏ ½ºÆ®¸² I/O ÇÔ¼öÀÎ fopen(),fclose()¿Í ¸Å¿ì ºñ½ÁÇÏ´Ù´Â °ÍÀ» ¾Ë¾ÒÀ» °ÍÀÌ´Ù. {{{ LIBRARY FUNCTION: pclose(); PROTOTYPE: int pclose( FILE *stream ); RETURNS: wait4() È£ÃâÀÇ Å»Ãâ »óÅÂ(exit status) -1 ½ºÆ®¸²("stream")ÀÌ À¯È¿ÇÏÁö ¾Ê°Å³ª wait4()°¡ ½ÇÆÐÇßÀ¸¸é NOTES: ÆÄÀÌÇÁ ÇÁ·Î¼¼½º°¡ Á¾·áµÇ±â¸¦ ±â´Ù·È´Ù°¡ ½ºÆ®¸²À» ´Ý´Â´Ù. }}} pclose() ÇÔ¼ö´Â popen()¿¡ ÀÇÇØ »ý¼º(fork)µÈ ÇÁ·Î¼¼½º¿¡ ´ëÇØ wait4()¸¦ ¼öÇàÇÑ´Ù. wait4()·ÎºÎÅÍ ¹ÝȯµÉ ¶§, ÆÄÀÌÇÁ¿Í ÆÄÀÏ ½ºÆ®¸²À» Æı«ÇÑ´Ù. ÀϹÝÀûÀÎ ½ºÆ®¸²¿¡ ±âÃÊÇÑ ÆÄÀÏ I/O¿¡ ´ëÇÑ fclose() ÇÔ¼ö¿Í µ¿ÀǾî¶ó ÇÒ ¼ö ÀÖ´Ù. sort¸í·É¾î·Î ÆÄÀÌÇÁ¸¦ ¿­¾î ¹®ÀÚ¿­ÀÇ ¹è¿­À» Á¤·Äó¸®ÇÏ´Â ¿¹Á¦¸¦ »ìÆ캸ÀÚ: {{{#!vim c /***************************************************************************** ¸®´ª½º ÇÁ·Î±×·¥¸Ó¸¦ À§ÇÑ °¡À̵å - 6Àå ¿¡¼­ ¹ßÃé (C)opyright 1994-1995, Scott Burkett ***************************************************************************** MODULE: popen1.c *****************************************************************************/ #include #define MAXSTRS 5 int main(void) { int cntr; FILE *pipe_fp; char *strings[MAXSTRS] = { "echo", "bravo", "alpha", "charlie", "delta"}; ^I/*popen() È£ÃâÀ» »ç¿ëÇÏ¿© ´Ü¹æÇâ ÆÄÀÌÇÁ¸¦ ¸¸µç´Ù*/ if (( pipe_fp = popen("sort", "w")) == NULL) { perror("popen"); exit(1); } ^I/*¹Ýº¹ ó¸®*/ for(cntr=0; cntr /tmp/foo", "w"); popen("sort | uniq | more", "w"); }}} popen()ÀÇ ¶Ç ´Ù¸¥ ¿¹ÀÎ, µÎ°³ÀÇ ÆÄÀÌÇÁ(Çϳª´Â ls, ´Ù¸¥ Çϳª´Â sort)¸¦ ¿©´Â ÀÛÀº ÇÁ·Î±×·¥À» »ìÆ캸ÀÚ: {{{#!vim c /***************************************************************************** ¸®´ª½º ÇÁ·Î±×·¥¸Ó¸¦ À§ÇÑ °¡À̵å - 6Àå ¿¡¼­ ¹ßÃé (C)opyright 1994-1995, Scott Burkett ***************************************************************************** MODULE: popen2.c *****************************************************************************/ #include int main(void) { FILE *pipein_fp, *pipeout_fp; char readbuf[80]; ^I/*popen() È£ÃâÀ» »ç¿ëÇÏ¿© ´Ü¹æÇâ ÆÄÀÌÇÁ¸¦ ¸¸µç´Ù*/ if (( pipein_fp = popen("ls", "r")) == NULL) { perror("popen"); exit(1); } ^I/*popen() È£ÃâÀ» »ç¿ëÇÏ¿© ´Ü¹æÇâ ÆÄÀÌÇÁ¸¦ ¸¸µç´Ù*/ if (( pipeout_fp = popen("sort", "w")) == NULL) { perror("popen"); exit(1); } ^I/*¹Ýº¹ ó¸®*/ while(fgets(readbuf, 80, pipein_fp)) fputs(readbuf, pipeout_fp); ^I/*ÆÄÀÌÇÁ¸¦ ´Ý´Â´Ù*/ pclose(pipein_fp); pclose(pipeout_fp); return(0); } }}} popen()ÀÇ ¸¶Áö¸· ¿¹Á¦¸¦ À§ÇØ, ³Ñ°Ü¹ÞÀº ¸í·É¾î¿Í ÆÄÀÏ¸í°£ÀÇ ÆÄÀÌÇÁ¶óÀÎÀ» ¿©´Â ÀϹÝÀûÀÎ ÇÁ·Î±×·¥À» ÀÛ¼ºÇØ º¸ÀÚ: {{{#!vim c /***************************************************************************** ¸®´ª½º ÇÁ·Î±×·¡¸Ó¸¦ À§ÇÑ °¡À̵å - 6Àå ¿¡¼­ ¹ßÃé (C)opyright 1994-1995, Scott Burkett ***************************************************************************** MODULE: popen3.c *****************************************************************************/ #include int main(int argc, char *argv[]) { FILE *pipe_fp, *infile; char readbuf[80]; if( argc != 3) { fprintf(stderr, "USAGE: popen3 [command] [filename]\n"); exit(1); } ^I/*ÀÔ·Â ÆÄÀÏÀ» ¿¬´Ù*/ if (( infile = fopen(argv[2], "rt")) == NULL) { perror("fopen"); exit(1); } ^I/*popen() È£ÃâÀ» »ç¿ëÇÏ¿© ´Ü¹æÇâ ÆÄÀÌÇÁ¸¦ ¸¸µç´Ù*/ if (( pipe_fp = popen(argv[1], "w")) == NULL) { perror("popen"); exit(1); } ^I/*¹Ýº¹ ó¸®*/ do { fgets(readbuf, 80, infile); if(feof(infile)) break; fputs(readbuf, pipe_fp); } while(!feof(infile)); fclose(infile); pclose(pipe_fp); return(0); } }}} ´ÙÀ½ÀÇ ¿¹¸¦ °¡Áö°í ÀÌ ÇÁ·Î±×·¥À» ¼öÇà½ÃÄѺ¸ÀÚ: {{{ popen3 sort popen3.c popen3 cat popen3.c popen3 more popen3.c popen3 cat popen3.c | grep main }}} ==== ÆÄÀÌÇÁÀÇ Atomic µ¿ÀÛ (Atomic Operations with Pipes) ==== ¿øÀÚÈ­(Atomic)°¡ °í·ÁµÇ¾î¾ß ÇÏ´Â µ¿ÀÛµéÀº ¾î¶² ÀÌÀ¯¿¡¼­°Ç ¼öÇàÀ» Çϴµ¥ ¹æÇظ¦ ¹Þ¾Æ¼­´Â ¾ÊµÈ´Ù. ÀüüÀÇ µ¿ÀÛÀÌ Çѹø¿¡ ÀϾ´Ù. POSIX Ç¥ÁØÀº /usr/include/posix1_lim.h ÆÄÀÏ¿¡ ÆÄÀÌÇÁÀÇ ¿øÀÚ(Atomic) µ¿ÀÛÀ» À§ÇÑ ÃÖ´ë ¹öÆÛÀÇ Å©±â¸¦ ¸í½ÃÇÏ°í ÀÖ´Ù.: {{{#!vim c #define _POSIX_PIPE_BUF 512 }}} ÀÚµ¿ÀûÀ¸·Î ÆÄÀÌÇÁ·Î ºÎÅÍ 512¹ÙÀÌÆ®±îÁö ¾²°Å³ª ÀÐÀ» ¼ö ÀÖ´Ù. »çÀÌ¿¡ °ÉÃÄÁö´Â °ÍÀº ÂÉ°³¾î Áú °ÍÀ̸ç, ¿øÀÚÈ­(Atomic)µÇÁö ¾Ê´Â´Ù. ¸®´ª½º¿¡¼­ ¿øÀÚÈ­(Atomic)µÇ´Â µ¿ÀÛÀÇ ÇÑ°è´Â "linux/limits.h" ÆÄÀÏ¿¡ Á¤ÀǵǾî ÀÖ´Ù.: {{{#!vim #define PIPE_BUF 4096 }}} º¸´Ù½ÃÇÇ, ¸®´ª½º´Â POSIX¿¡¼­ ÇÊ¿ä·Î ÇÏ´Â ÃÖ¼ÒÇÑÀÇ ¹ÙÀÌÆ®¸¦ ¼ö¿ëÇÑ´Ù. ÆÄÀÌÇÁ µ¿ÀÛÀÇ ¿øÀÚÈ­(Atomicity)´Â ÇÑ°³ ÀÌ»óÀÇ ÇÁ·Î¼¼½º(FIFOS)°¡ Æ÷Ç﵃ ¶§ Áß¿äÇÏ°Ô µÈ´Ù. ¿¹¸¦ µé¾î ÆÄÀÌÇÁ¿¡ ¾²¿©Áö´Â ¹ÙÀÌÆ®ÀÇ ¼ö°¡ ÇÑ°³ÀÇ µ¿ÀÛÀÇ ¿øÀÚ ÇÑ°è(Atomic Limit)¸¦ ÃÊ°úÇϰųª º¹¼ö°³ÀÇ ÇÁ·Î¼¼½º°¡ ÆÄÀÌÇÁ¸¦ ¾²°í ÀÖ´Â °æ¿ì, ÀÚ·á´Â »çÀÌ¿¡ ³¢¿ö ³Ö¾îÁö°Å³ª(interleaved) ³»´øÁ® Áú °Í ÀÌ´Ù(chunked). ¹Ù²ã ¸»Çϸé, ÇÑ ÇÁ·Î¼¼½º°¡ ¾²±â¸¦ ¼öÇàÇÏ´Â µ¿¾È ´Ù¸¥ ÇÁ·Î¼¼½º°¡ ÆÄÀÌÇÁ¶óÀο¡ ÀڷḦ ³ÖÀ» ¼ö ÀÖ´Ù´Â °ÍÀÌ´Ù. ==== ¹ÝÀÌÁß ÆÄÀÌÇÁÀÇ Á¤¸® (Note on half-duplex pipes) ==== * µÎ°³ÀÇ ÆÄÀÌÇÁ¸¦ ¿­¾î ÀÚ½Ä ÇÁ·Î¼¼½º¿¡ Àû´çÇÑ ÆÄÀÏ ½Äº°ÀÚ¸¦ ÀçÁöÁ¤ÇÏ¿© ¾ç¹æÇâ ÆÄÀÌÇÁ¸¦ ¸¸µé ¼ö ÀÖ´Ù. * fork()¸¦ È£ÃâÇϱâ Àü¿¡ pipe()¸¦ È£ÃâÇÏ¿©¾ß ÇÑ´Ù. ±×·¸Áö ¾ÊÀ¸¸é ½Äº°ÀÚ´Â ÀڽĿ¡°Ô »ó¼ÓµÇÁö ¾ÊÀ» °ÍÀÌ´Ù. (popen()µµ ¸¶Âù°¡ÁöÀÓ) * ¹ÝÀÌÁß ÆÄÀÌÇÁ¸¦ °¡Áö°í ¼­·Î ¿¬°áµÈ ÇÁ·Î¼¼½ºµéÀº Ä£Á·°ü°è(¸ðÀÚ°ü°è,parent-child)¸¦ °øÀ¯Çؾ߸¸ ÇÑ´Ù. ÆÄÀÌÇÁ´Â Ä¿³ÎÀÇ ¿µ¿ª¿¡ Á¸ÀçÇÔÀ¸·Î ÆÄÀÌÇÁÀÇ »ý¼ºÀÚ¿Í Ä£Á·°ü°è¿¡ ÀÖÁö ¾Ê´Â ÇÁ·Î¼¼½º´Â ±×°ÍÀÇ ÁÖ¼Ò¸¦ ÁöÁ¤ÇÒ ¹æ¹ýÀÌ ¾ø´Ù. À̸§À» °¡Áø ÆÄÀÌÇÁ(named pipes:FIFOS)ÀÇ °æ¿ì´Â ´Ù¸£´Ù. === À̸§À» °¡Áø ÆÄÀÌÇÁ(Named pipes:FIFOs - First In First Out) === ==== ±âº» °³³ä (Basic Concepts) ==== À̸§À» °¡Áø ÆÄÀÌÇÁ´Â ´ëÁֺРÀÏ¹Ý ÆÄÀÌÇÁ¿Í °°ÀÌ ÀÛ¾÷ÇÏÁö¸¸, ¸î°¡Áö ÁÖ¸ñÇÒ¸¸ÇÑ Â÷ÀÌÁ¡ÀÌ ÀÖ´Ù. * À̸§À» °¡Áø ÆÄÀÌÇÁ(Named pipes)´Â ÆÄÀÏ ½Ã½ºÅ۾ȿ¡ Ưº°ÇÑ ÀåÄ¡ ÆÄÀÏ(device special file) ó·³ Á¸ÀçÇÑ´Ù. * ´Ù¸¥ Ä£Á·°ü°è¿¡ ÀÖ´Â ÇÁ·Î¼¼½ºµéµµ À̸§À» °¡Áø ÆÄÀÌÇÁ(named pipe)¸¦ ÅëÇØ ÀڷḦ °øÀ¯ÇÒ ¼ö ÀÖ´Ù. * °øÀ¯ÇÏ°í ÀÖ´Â ÇÁ·Î¼¼½ºµé¿¡ ÀÇÇØ ¸ðµç I/O°¡ ¼öÇàµÈ ÈÄ¿¡µµ À̸§À» °¡Áø ÆÄÀÌÇÁ(named pipe)´Â ³ªÁßÀÇ »ç¿ëÀ» À§ÇØ ÆÄÀÏ ½Ã½ºÅÛ¿¡ ³²¾Æ Àִ´Ù. ==== FIFO ¸¸µé±â (Creating a FIFO) ==== À̸§À» °¡Áø ÆÄÀÌÇÁ(named pipe)¸¦ ¹æ¹ý¿¡´Â ¸î°¡Áö°¡ ÀÖ´Ù. óÀ½ µÎ°¡Áö´Â ½©·Î ºÎÅÍ Á÷Á¢ ¸¸µå´Â °ÍÀÌ´Ù. {{{ mknod MYFIFO p mkfifo a=rw MYFIFO }}} À§ÀÇ µÎ ¸í·É¾î´Â ÇѱâÁö ¿¹¿Ü¸¦ Á¦¿ÜÇÏ°í µ¿ÀÏÇÑ µ¿ÀÛÀ» ¼öÇàÇÑ´Ù. mkfifo ¸í·É¾î´Â ÆÄÀÌÇÁ¸¦ ¸¸µç ÈÄ FIFO ÆÄÀÏ¿¡ ´ëÇØ Á÷Á¢ Çã°¡»çÇ×(permission)À» ¹Ù ²Ù±â À§ÇÑ Ç׸ñÀ» Á¦°øÇÑ´Ù. mknodÀÇ °æ¿ì´Â chmod ¸í·É¾îÀÇ ºü¸¥ È£ÃâÀÌ ÇÊ¿äÇÒ °ÍÀÌ´Ù. FIFO ÆÄÀÏÀº ±ä µð·ºÅ丮 ¸®½ºÆ®(long directory listing)¿¡¼­ º¸¿©Áö´Â "p" Áö½ÃÀÚ¿¡ ÀÇÇØ ¹°¸®ÀûÀÎ ÆÄÀÏ ½Ã½ºÅÛ¿¡ À绡¸® ¾Ë·ÁÁø´Ù. {{{ $ ls -l MYFIFO prw-r--r-- 1 root root 0 Dec 14 22:15 MYFIFO| }}} ÆÄÀÏ¸í ´ÙÀ½¿¡ ÀÖ´Â ¼öÁ÷¼±("pipe sign")¿¡ ÁÖ¸ñÇ϶ó. C·Î FIFO¸¦ ¸¸µé±â À§ÇØ, mknod() ½Ã½ºÅÛ È£ÃâÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù.: {{{ LIBRARY FUNCTION: mknod(); PROTOTYPE: int mknod( char *pathname, mode_t mode, dev_t dev); RETURNS: 0 on success, -1 on error: errno = EFAULT (pathname invalid) EACCES (permission denied) ENAMETOOLONG (pathname too long) ENOENT (invalid pathname) ENOTDIR (invalid pathname) (see man page for mknod for others) NOTES: Creates a filesystem node (file, device file, or FIFO) }}} man ÆäÀÌÁö¿¡ mknod()¿¡ ´ëÇÑ º¸´Ù ÀÚ¼¼ÇÑ ³»¿ëÀ» ³²±æÅ×Áö¸¸, C·Î ¸¸µé¾îÁø FIFOÀÇ °£´ÜÇÑ ¿¹¸¦ »ìÆ캸ÀÚ.: {{{#!vim c mknod("/tmp/MYFIFO", S_IFIFO|0666, 0); }}} ÀÌ °æ¿ì, "/tmp/MYFIFO" ÆÄÀÏÀº FIFO ÆÄÀÏó·³ ¸¸µé¾î Áø´Ù. ´ÙÀ½Ã³·³ ÁöÁ¤µÈ umask¿¡ ÀÇÇØ ¿µÇâÀ» ¹Þ´Â´Ù ÇÏ´õ¶óµµ ¿äûµÈ Çã°¡»çÇ×(permission)Àº "0666"ÀÌ´Ù.: {{{#!vim c final_umask = requested_permissions & ~original_umask }}} ÀϹÝÀûÀÎ ¹æ¹ýÀº ÀϽÃÀûÀ¸·Î umask °ªÀ» °ø°ÝÇϱâ À§ÇØ umask() ½Ã½ºÅÛ È£ÃâÀ» »ç¿ëÇÏ´Â °ÍÀÌ´Ù.: {{{#!vim c umask(0); mknod("/tmp/MYFIFO", S_IFIFO|0666, 0); }}} °Ô´Ù°¡, µð¹ÙÀ̽º ÆÄÀÏÀ» ¸¸µé°í ÀÖÁö ¾Ê´Ù¸é mknod()ÀÇ ¼¼¹ø° ¾Æ±Ô¸ÕÆ®´Â ¹«½ÃµÈ´Ù. ÀÌ·± °æ¿ì¿¡´Â µð¹ÙÀ̽º ÆÄÀÏÀÇ Å«ÂÊ°ú ÀÛÀº ÂÊÀÇ ¹øÈ£¸¦ ÁöÁ¤ÇØ ÁÖ¾î¾ß¸¸ ÇÑ´Ù. ==== FIFO µ¿ÀÛ (FIFO Operations) ==== FIFOÀÇ I/O µ¿ÀÛÀº ÇÑ°³ÀÇ ÁÖ¿äÇÑ Â÷ÀÌÁ¡À» Á¦¿ÜÇÏ°í º»ÁúÀûÀ¸·Î ÀÏ¹Ý ÆÄÀÌÇÁ¿Í °°´Ù. "open" ½Ã½ºÅÛ È£ÃâÀ̳ª ¶óÀ̺귯¸® ÇÔ¼ö´Â ¹°¸®ÀûÀ¸·Î ÆÄÀÌÇÁÀÇ Ã¤³ÎÀ» ¿©´Âµ¥ »ç¿ëµÇ¾îÁ®¾ß ÇÑ´Ù. ¹ÝÀÌÁß ÆÄÀÌÇÁ¿¡¼­´Â ÆÄÀÌÇÁ°¡ ¹°¸®ÀûÀÎ ÆÄÀÏ ½Ã½ºÅÛÀÌ ¾Æ´Ñ, Ä¿³Î¿¡ Á¸ÀçÇÔÀ¸·Î ºÒÇÊ¿äÇÏ´Ù. ¿¹Á¦¿¡¼­ ¿ì¸®´Â ÆÄÀÌÇÁ¸¦ fopen()À¸·Î ÆÄÀÏÀ» ¿­°í, fclose()·Î ´Ý´Â ½ºÆ®¸²(stream)ó·³ ´Ù·ê °Í ÀÌ´Ù. °£´ÜÇÑ ¼­¹ö ÇÁ·Î¼¼½º¸¦ »ìÆ캸ÀÚ: {{{#!vim c /***************************************************************************** ¸®´ª½º ÇÁ·Î±×·¡¸Ó¸¦ À§ÇÑ °¡À̵å - 6Àå ¿¡¼­ ¹ßÃé (C)opyright 1994-1995, Scott Burkett ***************************************************************************** MODULE: fifoserver.c *****************************************************************************/ #include #include #include #include #include #define FIFO_FILE "MYFIFO" int main(void) { FILE *fp; char readbuf[80]; ^I/*ÆÄÀÌÇÁ°¡ Á¸ÀçÇÏÁö ¾ÊÀ¸¸é ¸¸µç´Ù*/ umask(0); mknod(FIFO_FILE, S_IFIFO|0666, 0); while(1) { fp = fopen(FIFO_FILE, "r"); fgets(readbuf, 80, fp); printf("Received string: %s\n", readbuf); fclose(fp); } return(0); } }}} µðÆúÆ®·Î FIFO´Â Â÷´ÜµÊÀ¸·Î, ÄÄÆÄÀÏÇÑ ÈÄ¿¡ ¹é±×¶ó¿îµå·Î server¸¦ ½ÇÇà½ÃÄѶó: {{{ $ fifoserver& }}} Àá½Ã FIFOÀÇ Â÷´Ü µ¿ÀÛ¿¡ ´ëÇØ ¸»ÇÏ°Ú´Ù. ¸ÕÀú, ¼­¹ö¿¡ ´ëÇÑ ´ÙÀ½ÀÇ °£´ÜÇÑ Å¬¶óÀ̾ðÆ® º¯È¯ºÎ(frontend)¸¦ »ìÆ캸ÀÚ: {{{#!vim c /***************************************************************************** ¸®´ª½º ÇÁ·Î±×·¡¸Ó¸¦ À§ÇÑ °¡À̵å - 6Àå ¿¡¼­ ¹ßÃé (C)opyright 1994-1995, Scott Burkett ***************************************************************************** MODULE: fifoclient.c *****************************************************************************/ #include #include #define FIFO_FILE "MYFIFO" int main(int argc, char *argv[]) { FILE *fp; if ( argc != 2 ) { printf("USAGE: fifoclient [string]\n"); exit(1); } if((fp = fopen(FIFO_FILE, "w")) == NULL) { perror("fopen"); exit(1); } fputs(argv[1], fp); fclose(fp); return(0); } }}} ==== FIFOÀÇ µ¿ÀÛ Â÷´Ü (Blocking Actions on a FIFO) ==== ÀϹÝÀûÀ¸·Î Â÷´ÜÀº FIFO¿¡¼­ ¹ß»ýÇÑ´Ù. ¹Ù²Ù¾î ¸»Çϸé, FIFO°¡ Àб⸦ À§ÇØ ¿­·ÁÁ® ÀÖ´Ù¸é, ÇÁ·Î¼¼½º´Â ´Ù¸¥ ÇÁ·Î¼¼½ºµéÀÌ ¾²±â¸¦ À§ÇØ ¿­·Á°í ÇÒ ¶§±îÁö Â÷´Ü(block)½Ãų °ÍÀÌ´Ù. ÀÌ·¯ÇÑ µ¿ÀÛÀº ¹Ý´ë·Îµµ ¼öÇàµÈ´Ù. ÀÌ·¯ÇÑ µ¿ÀÛµéÀ» ¿øÇÏÁö ¾Ê´Â´Ù¸é, µðÆúÆ® µ¿ÀÛ Â÷´Ü ±â´ÉÀ» »ç¿ëÇÏÁö ¾Êµµ·Ï open() È£Ãâ½Ã¿¡ O_NONBLOCK Ç÷¡±×¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. °£´ÜÇÑ ¼­¹öÀÇ °æ¿ì, ¹é±×¶ó¿îµå·Î ¹Ð¾î³»°í, °Å±â¼­ Â÷´ÜµÈ ä·Î ³²°ÜµÐ´Ù. ¶Ç ´Ù¸¥ ¹æ¹ýÀº ¶Ç ´Ù¸¥ °¡»óÀÇ ÄַܼΠ¶Ù¾îµé¾î Ŭ¶óÀ̾ðÆ® ÂÊÀ» ½ÇÇà½ÃÅ°°í ¼öÇà°á°ú¸¦ ¾Õ,µÚ·Î Àüȯ½ÃÅ°´Â °ÍÀÌ´Ù. ==== Àß ¾Ë·ÁÁöÁö ¾ÊÀº SIGPIPE ½ÅÈ£ (The Infamous SIGPIPE Signal) ==== ¸¶Áö¸· Á¤¸®·Î, ÆÄÀÌÇÁ´Â Àбâ¿Í ¾²±â¸¦ ÇÒ ¼ö ÀÖ´Ù. ÇÁ·Î¼¼½º°¡ ÀбⰡ ¾ÈµÇ´Â ÆÄÀÌÇÁ¿¡ ¾²·Á°í ÇÑ´Ù¸é, Ä¿³Î·Î ºÎÅÍ SIGPIPE ½ÅÈ£¸¦ ¹Þ°Ô µÈ´Ù. ÀÌ°ÍÀº µÎ°³ ÀÌ»óÀÇ ÇÁ·Î¼¼½º°¡ ÆÄÀÌÇÁ¶óÀο¡ Æ÷ÇԵǾî ÀÖÀ» ¶§ ÇʼöÀûÀÌ´Ù. === ½Ã½ºÅÛ V IPC (System V IPC) === ==== ±âº»ÀûÀÎ °³³ä (Fundamental Concepts) ==== ½Ã½ºÅÛ V»ó¿¡¼­ AT&T´Â IPC ¼³ºñÀÇ °®´Â ¼¼°¡Áö »õ·Î¿î ÇüÅÂ(¸Þ¼¼Áö Å¥(message queue), ¼¼¸¶ÆÛ(semaphores), °øÀ¯ ¸Þ¸ð¸®(shared memory))¸¦ ¼Ò°³Çß´Ù. POSIX À§¿øȸ¿¡¼­´Â ¾ÆÁ÷ ÀÌ ¼¼°¡Áö ¼³ºñ¿¡ ´ëÇÑ Ç¥ÁØÈ­¸¦ ¸¶Ä¡Áö ¸øÇÏ°í ÀÖÁö¸¸, ´ëºÎºÐÀÇ ±¸ÇöµéÀº À̵éÀ» Áö¿øÇÏ°í ÀÖ´Ù. ´õ±º´Ù³ª ¹öŬ¸®(BSD)´Â ½Ã½ºÅÛ V ¿ä¼Òº¸´Ù´Â ¼ÒÄÏÀ» IPCÀÇ ±âÃÊ ÇüÅ·Π»ç¿ëÇÑ´Ù. µÞÀå¿¡¼­ ¼ÒÄÏ¿¡ ´ëÇØ ³íÇÏ°ÚÁö¸¸, ¸®´ª½º´Â IPCÀÇ µÎ°¡Áö ÇüÅÂ(BSD¿Í System V)¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ½Ã½ºÅÛ V IPCÀÇ ¸®´ª½º ±¸ÇöÀº Krishna balasubramanian(balasub@cis.ohio-state.edu)¿¡ ÀÇÇØ ±â¼úµÇ¾ú´Ù. ===== IPC È®ÀÎÀÚ (IPC Identifiers) ===== °¢°¢ÀÇ IPC °´Ã¼(Object)Àº ±×°Í°ú ¿¬°üµÈ À¯ÀÏÇÑ IPC È®ÀÎÀÚ(Identifier)¸¦ °®´Â´Ù. "IPC °´Ã¼(object)"¶ó°í ÇÔÀº ´ÜÀÏ ¸Þ¼¼Áö Å¥(single message queue), ¼¼¸¶ÆÛ ÁýÇÕ(semaphore set), ¶Ç´Â °øÀ¯ ¸Þ¸ð¸® ¼¼±×¸ÕÆ®(shared memory segment)¸¦ ¸»ÇÑ´Ù. IPC °´Ã¼¿¡ ´ëÇÑ ¿ìÀÏÇÑ È®ÀÎÀÚ´Â Ä¿³Î ¾È¿¡¼­ »ç¿ëµÈ´Ù. ¿¹¸¦ µé¸é, Ưº°ÇÑ °øÀ¯ ¸Þ¸ð¸® ¼¼±×¸ÕÆ®¿¡ Á¢±ÙÇϱâ À§ÇØ ±× ¼¼±×¸ÕÆ®¿¡ ÇÒ´çµÈ À¯ÀÏÇÑ ID °ªÀÌ ÇÊ¿äÇÏ´Ù. È®ÀÎÀÚÀÇ À¯ÀϼºÀº ¹®Á¦ÀÇ °´Ã¼ ŸÀÔ(type)°ú °ü°è ÀÖ´Ù. À̸¦ ¼³¸íÇϱâ À§ÇØ, "12345"¶ó´Â ¼öÄ¡ È®ÀÎÀÚ¸¦ °¡Á¤ÇÏÀÚ. °°Àº È®ÀÎÀÚ¸¦ °°´Â µÎ°³ÀÇ ¸Þ¼¼Áö Å¥´Â ¾øÀ¸¹Ç·Î, °°Àº ¼öÄ¡ È®ÀÎÀÚ¸¦ °¡Áø °øÀ¯ ¸Þ¸ð¸® ¼¼±×¸ÕÆ®¿Í ¸Þ¼¼Áö Å¥¸¦ ±¸º°ÇÒ ¼ö ÀÖ´Â °¡´É¼ºÀÌ Á¸ÀçÇÑ´Ù. ===== IPC Å° (IPC Keys) ===== À¯ÀÏÇÑ ID¸¦ ¾ò±âÀ§ÇØ, Å°(key)°¡ »ç¿ëµÇ¾îÁ®¾ß ÇÑ´Ù. Å°(key)´Â Ŭ¶óÀ̾ðÆ®¿Í ¼­¹ö ÇÁ·Î¼¼½º°£¿¡ ¼­·Î µ¿ÀǵǾî¾ß ÇÑ´Ù. ÀÌ°ÍÀº ÀÀ¿ëÇÁ·Î±×·¥À» À§ÇÑ Å¬¶óÀ̾ðÆ®/¼­¹ö üÁ¦¸¦ ±¸¼ºÇϴ ù¹ø° ´Ü°è¸¦ ÀǹÌÇÑ´Ù. ´ç½ÅÀÌ ´©±º°¡¿¡°Ô ÀüÈ­¸¦ ÇÏ°íÀÚ ÇÒ ¶§´Â ÀüÈ­¹øÈ£¸¦ ¾Ë°í ÀÖ¾î¾ß ÇÑ´Ù. °Ô´Ù°¡ ÀüÈ­ ȸ»ç´Â ´ç½Å¿¡°Ô¼­ ³ª°¡´Â ÀüÈ­¸¦ ¸¶Áö¸· ¸ñÀûÁö±îÁö ¾î¶»°Ô Áß°èÇÒ °ÍÀÎÁö ¾Ë°í ÀÖ¾î¾ß ÇÑ´Ù. ¹Ý´ëÆíÀÌ ÀüÈ­¿¡ ÀÀ´äÇØ¾ß ¿¬°áÀÌ ÀÌ·ç¾î Áø´Ù. ½Ã½ºÅÛ V IPC ¼³ºñÀÇ °æ¿ì, ÀüÈ­´Â »ç¿ëµÇ´Â °´Ã¼ÀÇ Å¸ÀÔÀ» °¡Áö°í Á÷Á¢ÀûÀÎ °ü·ÃÀÌ ÀÖ´Ù. ÀüÈ­ ȸ»ç³ª ¶ó¿ìÆà ¹æ¹ý(routing method)Àº IPC Å°(key)¿Í ÀûÁ¢ ¿¬°üµÇ¾î Áø´Ù. Å°´Â ÀÀ¿ëÇÁ·Î±×·¥¿¡¼­ Å°°ªÀ» ÇϵåÄÚµùÇÔÀ¸·Î½á Ç×»ó °°Àº °ªÀ» °¡Áú ¼ö ÀÖ´Ù. ÀÌ°ÍÀº Å°°¡ ÀÌ¹Ì »ç¿ëµÈ °ÍÀÏ ¼ö ÀÖ´Ù´Â ´ÜÁ¡ÀÌ ÀÖ´Ù. Á¾Á¾ ftok() ÇÔ¼ö´Â Ŭ¶óÀ̾ðÆ®¿Í ¼­¹ö ¸ðµÎ¿¡ ÀÇÇØ Å°°ªÀ» ¹ß»ý½ÃÅ°´Âµ¥ »ç¿ëµÈ´Ù. {{{ LIBRARY FUNCTION: ftok(); PROTOTYPE: key_t ftok ( char *pathname, char proj ); RETURNS: new IPC key value if successful -1 if unsuccessful, errno set to return of stat() call }}} ftok()·Î ºÎÅÍ ¹ÝȯµÈ Å°°ªÀº ù¹ø° ¾Æ±Ô¸ÕÆ®ÀÎ ÆÄÀÏ·Î ºÎÅÍ inode ¹øÈ£, minor ÀåÄ¡¹øÈ£¿Í µÎ¹ø° ¾Æ±Ô¸ÕÆ®ÀÎ ÇѱÛÀÚ ÇÁ·ÎÁ§Æ® È®ÀÎÀÚÀÇ Á¶ÇÕ¿¡ ÀÇÇØ ¹ß»ýÇÑ´Ù. ÀÌ°ÍÀº À¯ÀϼºÀ» º¸ÀåÇÏÁö ¾ÊÁö¸¸, ÀÀ¿ëÇÁ·Î±×·¥Àº Ãæµ¹À» üũÇÏ¿© Å°¸¦ ´Ù½Ã ¹ß»ý½Ãų ¼ö ÀÖ´Ù. {{{#!vim c key_t mykey; mykey = ftok("/tmp/myapp",'a'); }}} À§ÀÇ ¿¹¿¡¼­, µð·ºÅ丮 "/tmp/myapp"´Â 'a'¶ó´Â ÇѱÛÀÚ¿Í Á¶ÇյȴÙ. ¶Ç ´Ù¸¥ ÀϹÝÀûÀÎ ¿¹´Â ÇöÀç µð·ºÅ丮¸¦ »ç¿ëÇÏ´Â °ÍÀÌ´Ù. {{{#!vim c key_t mykey; mykey = ftok(".",'a'); }}} »ç¿ëµÇ´Â Å° ¹ß»ý ¾Ë°í¸®ÁòÀº ÀüÀûÀ¸·Î ÀÀ¿ëÇÁ·Î±×·¥ ÇÁ·Î±×·¡¸ÓÀÇ ¸¶À½¿¡ ´Þ·Á ÀÖ´Ù. ÃøÁ¤ÀÌ µ¥µå¶ô(deadlocks), °æÀï»óÅÂÀÇ ¹æÁöµî¿¡ ÀÖ´Â ÇÑ, ¾î¶² ¹æ¹ýÀÌµç ³ªÅ¸³¯ ¼ö ÀÖ´Ù. ¿¹Á¦ÀÇ ¸ñÀûÀº ftok()ÀÇ »ç¿ë¿¡ ÀÖ´Ù. ¸¸¾à °¢ Ŭ¶óÀ̾ðÆ® ÇÁ·Î¼¼½º°¡ °¢±â À¯ÀÏÇÑ È¨ µð·ºÅ丮·Î ºÎÅÍ ¼öÇàµÉ °ÍÀ̶ó°í °¡Á¤ÇÑ´Ù¸é, ¹ß»ýµÇ´Â Å°´Â ¿ì¸®ÀÇ Çʿ並 ÃæÁ·½ÃÄÑ¾ß ÇÑ´Ù. ¾ò¾îÁø Å°°ªÀº IPC °´Ã¼¸¦ ¸¸µé°í Á¢±ÙÇϱâ À§ÇØ ÀÏ·ÃÀÇ IPC ½Ã½ºÅÛ È£Ãâ¿¡¼­ »ç¿ëµÈ´Ù. ===== ipcs ¸í·É¾î (The ipcs Command) ===== ipcs ¸í·É¾î´Â ¸ðµç ½Ã½ºÅÛ V IPC °´Ã¼ÀÇ »óŸ¦ ¾ò´Âµ¥ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÀÌ ÅøÀÇ ¸®´ª½º ¹öÀüÀº Krishna Balasubramanian¿¡ ÀÇÇØ Á¦À۵Ǿú´Ù. {{{ ipcs -q: ¸Þ¼¼Áö Å¥(message queues)¸¸À» º¸¿©ÁØ´Ù. ipcs -s: ¼¼¸¶ÆÛ(semaphore)¸¸À» º¸¿©ÁØ´Ù. ipcs -m: °øÀ¯ ¸Þ¸ð¸®(shared memory)¸¸À» º¸¿©ÁØ´Ù ipcs --help: ºÎ°¡ÀûÀÎ ¾Æ±Ô¸ÕÆ®(arguments) }}} µðÆúÆ®·Î ¼¼°¡Áö °´Ã¼ÀÇ Á¾·ù°¡ ¸ðµÎ º¸¿©Áø´Ù. ´ÙÀ½ÀÇ °£´ÜÇÑ ipcsÀÇ Ãâ·ÂÀ» »ìÆ캸ÀÚ: {{{ --- Shared Memory Segments --- shmid owner perms bytes nattch status --- Semaphore Arrays --- semid owner perms nsems status --- Message Queues --- msqid owner perms used-bytes messages 0 root 660 5 1 }}} ¿©±â¼­ ¿ì¸®´Â "0"À̶ó´Â È®ÀÎÀÚ(Identifier)¸¦ °¡Áø ´ÜÀÏ ¸Þ¼¼Áö Å¥(single message queue)¸¦ º¼ ¼ö ÀÖ´Ù. ±×°ÍÀÇ ÁÖÀÎÀº root »ç¿ëÀÚÀÌ°í, 660(-rw-rw--)ÀÇ 8Áø Çã°¡»çÇ×À» °¡Áö°í ÀÖ´Ù. Å¥¿¡´Â ÇÑ°³ÀÇ ¸Þ¼¼Áö°¡ ÀÖ°í, ¸Þ¼¼ÁöÀÇ ÃÑ Å©±â´Â 5¹ÙÀÌÆ®ÀÌ´Ù. ipcs ¸í·É¾î´Â IPC °´Ã¼¿¡ ´ëÇØ Ä¿³ÎÀÇ ÀúÀå Á¶Á÷À» ¿³º¼ ¼ö ÀÖ´Â °¡Àå °­·ÂÇÑ µµ±¸ÀÌ´Ù. ===== ipcrm ¸í·É¾î (The ipcrm Command) ===== ipcrm ¸í·É¾î´Â Ä¿³Î·Î ºÎÅÍ IPC °´Ã¼¸¦ Á¦°ÅÇϴµ¥ »ç¿ëµÈ´Ù. IPC °´Ã¼´Â »ç¿ëÀÚ Äڵ峻¿¡¼­ ½Ã½ºÅÛ È£ÃâÀ» °æ¿ìÇÏ¿© Á¦°ÅµÉ ¼ö ÀÖÀ¸¸ç, ƯÈ÷ °³¹ß ȯ°æÇÏ¿¡¼­ Á¾Á¾ ¼öµ¿À¸·Î IPC °´Ã¼¸¦ Á¦°ÅÇؾßÇÒ ÇÊ¿ä°¡ ¹ß»ýÇÑ´Ù. »ç¿ë¹ýÀº °£´ÜÇÏ´Ù.: {{{ ipcrm }}} Áö¿ï °´Ã¼°¡ ¸Þ¼¼Áö Å¥(msg)ÀÎÁö ¼¼¸¶ÆÛ(sem)ÀÎÁö °øÀ¯ ¸Þ¸ð¸®(shm)ÀÎÁö¸¦ °£´ÜÈ÷ ÁöÁ¤ÇÑ´Ù. IPC ID´Â ipcs ¸í·É¾î·Î ±¸ÇÒ ¼ö ÀÖ´Ù. È®ÀÎÀÚ´Â °°Àº ŸÀԾȿ¡¼­¸¸ À¯ÀÏÇÔÀ¸·Î °´Ã¼ÀÇ Å¸ÀÔÀ» ÁöÁ¤ÇØ ÁÖ¾î¾ß¸¸ ÇÑ´Ù. (¾ÕÀÇ ³»¿ëÀ» »ó±âÇ϶ó) ==== ¸Þ¼¼Áö Å¥ (Message Queues) ==== ===== ±âº» °³³ä (Basic Concepts) ===== ¸Þ¼¼Áö Å¥´Â Ä¿³ÎÀÇ ÁÖ¼Ò ¸Å°ÜÁø °ø°£(kernel's addressing space)¾ÈÀÇ ³»ºÎ ¿¬°á ¸ñ·Ï (Internal linked list)À̶ó´Â ¸»·Î °¡Àå Àß ¹¦»çµÉ ¼ö ÀÖ´Ù. ¸Þ¼¼ÁöµéÀº Â÷·Ê´ë·Î Å¥·Î º¸³»Áö°í ¿©·¯°¡Áö ´Ù¸¥ ¹æ¹ýÀ¸·Î Å¥·Î ºÎÅÍ Á¶È¸µÈ´Ù. (¹°·Ð) °¢°¢ÀÇ ¸Þ¼¼Áö Å¥´Â IPC È®ÀÎÀÚ(identifier)¿¡ ÀÇÇØ À¯ÀÏÇÏ°Ô È®ÀεȴÙ. ===== ³»ºÎ¿Í »ç¿ëÀÚ ÀÚ·á ±¸Á¶ (Internal and User Data Structures) ===== ½Ã½ºÅÛ V IPC¿Í °°ÀÌ º¹ÀâÇÑ ÁÖÁ¦¸¦ ÃæºÐÈ÷ ÀÌÇØÇϱâ À§ÇÑ ¿­¼è´Â ÇÑÁ¤µÈ Ä¿³Î ¾È¿¡ Á¸ÀçÇÏ´Â ´Ù¾çÇÑ ³»ºÎ ÀÚ·á ±¸Á¶¿Í Á÷Á¢ÀûÀ¸·Î Ä£ÇØÁö´Â °ÍÀÌ´Ù. ³ª¸ÓÁöµéÀÌ ´õ ³·Àº ´Ü°èÀÌ Á¸ÀçÇÏ°í ÀÖ´Â ÇÑ, ÀÌ·¯ÇÑ ±¸Á¶¿¡ ´ëÇÑ Á÷Á¢ÀûÀÎ Á¢±ÙÀº °¡Àå ±âº»ÀûÀÎ µ¿ÀÛ¿¡¼­ ÇÊ¿äÇÏ´Ù. '''''¸Þ¼¼Áö ¹öÆÛ (Message buffer)''''' ---- °¡Àå óÀ½À¸·Î ¸¸³¯ ±¸Á¶´Â msgbuf ±¸Á¶ÀÌ´Ù. ÀÌ Æ¯º°ÇÑ ÀÚ·á ±¸Á¶´Â ¸Þ¼¼Áö ÀڷḦ À§ÇÑ ÅÛÇø´(template)¶ó »ý°¢ÇÒ ¼ö ÀÖ´Ù. ÇÁ·Î±×·¡¸Ó°¡ ÀÌ·¯ÇÑ Å¸ÀÔÀÇ ±¸Á¶¸¦ Á¤ÀÇÇÏ¿© »ç¿ëÇÏÁö ¾Ê´Â ÇÑ, msgbuf ŸÀÔÀÇ ±¸Á¶¸¦ ½ÇÁ¦ÀûÀ¸·Î ÀÌÇØÇÏ´Â °ÍÀº ÇʼöÀûÀÌ´Ù. linux/msg.h¿¡ ´ÙÀ½°ú °°ÀÌ ¼±¾ðµÇ¾î ÀÖ´Ù.: {{{#!vim c /* message buffer for msgsnd and msgrcv calls */ /* msgsnd¿Í msgrcv È£ÃâÀ» À§ÇÑ ¸Þ¼¼Áö ¹öÆÛ */ struct msgbuf { long mtype; /* type of message ¸Þ¼¼Áö ŸÀÔ */ char mtext[1]; /* message text ¸Þ¼¼Áö ³»¿ë */ }; }}} msgbuf ±¸Á¶¿¡´Â µÎ°³ÀÇ ¸â¹ö°¡ ÀÖ´Ù.: '''mtype''' ¾ç¼ö·Î Ç¥ÇöµÇ´Â ¸Þ¼¼Áö ''ŸÀÔ''. ¹Ýµå½Ã ¾ç¼ö¿©¾ß ÇÑ´Ù. '''mtext''' ¸Þ¼¼Áö ÀÚ·á ÀÚü. ÁÖ¾îÁø ¸Þ¼¼Áö¿¡ ŸÀÔÀ» ºÎ¿©ÇÏ´Â ´É·ÂÀº º»ÁúÀûÀ¸·Î ´ÜÀÏ Å¥¿¡¼­ÀÇ ´ÙÁß(multiplex) ¸Þ¼¼ÁöµéÀ» ¼ö¿ëÇÒ ´É·ÂÀ» ºÎ¿©ÇÑ´Ù. ¿¹¸¦ µé¸é, Ŭ¶óÀ̾ðÆ® ÇÁ·Î¼¼½ºµéÀº ¸ÅÁ÷¹øÈ£ (magic number)¸¦ ÇÒ´ç¹ÞÀ» ¼ö ÀÖ°í ÀÌ°ÍÀº ¼­¹ö ÇÁ·Î¼¼½º·Î ºÎÅÍ º¸³»Áø ¸Þ¼¼Áöµé¿¡ ´ëÇØ ¸Þ¼¼Áö ŸÀÔó·³ »ç¿ëµÉ ¼ö ÀÖ´Ù. ¼­¹ö´Â ÀÚüÀûÀ¸·Î ¸î¸îÀÇ ´Ù¸¥ ¹øÈ£¸¦ »ç¿ëÇÒ ¼ö ÀÖ°í, Ŭ¶óÀ̾ðÆ®´Â ±×¹øÈ£·Î ¸Þ¼¼Áö¸¦ º¸³»±â À§ÇØ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¶Ç ´Ù¸¥ ½Ã³ª¸®¿À¿¡¼­´Â ÀÀ¿ëÇÁ·Î±×·¥Àº ¿¡·¯ ¸Þ¼¼Áö¿¡ ´ëÇØ ¸Þ¼¼Áö ŸÀÔ '1'¸¦ ¿äû ¸Þ¼¼Áö(request message)¿¡ ´ëÇØ ¸Þ¼¼Áö ŸÀÔ '2'¸¦ Ç¥½ÃÇÒ ¼ö ÀÖ´Ù. ÀÌ·¯ÇÑ °¡´É¼ºÀº ³¡ÀÌ ¾ø´Ù. ¶Ç ´Ù¸¥ ¹æ¹ýÀº ´ë°³ ¸Þ¼¼Áö ÀÚ·á ¿ä¼Ò (mtext)¿¡ ¸Å¿ì ¼­¼úÀûÀÎ À̸§À» ºÎ¿©ÇÏ¿© ÇöȤµÇÁö ¾Êµµ·Ï ÇÏ´Â °ÍÀÌ´Ù. ÀÌ Çʵå´Â ²À ¹®ÀÚµéÀÇ ¹è¿­ÀÌ¿©¾ß ÇÒ ÇÊ¿ä´Â ¾ø´Ù. ¾î¶² ÇüÅÂÀÇ ¾î¶² ÀÚ·áÀÌµç »ó°ü¾ø´Ù. ÀÌ ±¸Á¶´Â ÀÀ¿ëÇÁ·Î±×·¥ ÇÁ·Î±×·¡¸Ó¿¡ ÀÇÇØ ÀçÁ¤ÀÇµÉ ¼ö ÀÖÀ¸¹Ç·Î, ÇÊµå ±× ÀÚü¸¸À¸·Îµµ ½ÇÁ¦·Î ¿ÏÀüÈ÷ ¸¶À½´ë·ÎÀÌ´Ù. {{{#!vim c struct my_msgbuf { long mtype; /* Message type ¸Þ¼¼Áö ŸÀÔ */ long request_id; /* Request identifier ¿äû È®ÀÎÀÚ */ struct client info; /* Client information structure Ŭ¶óÀ̾ðÆ® Á¤º¸ ±¸Á¶ */ }; }}} Àü°ú °°Àº ¸Þ¼¼Áö ŸÀÔÀ» º¼ ¼ö ÀÖÁö¸¸, ±¸Á¶ÀÇ ³ª¸ÓÁö´Â µÎ°³ÀÇ ´Ù¸¥ ¿ä¼Ò·Î ¹Ù²î¾ú´Ù. ±× Áß Çϳª´Â ¶Ç ´Ù¸¥ ±¸Á¶Ã¼(structure)ÀÌ´Ù! ÀÌ°ÍÀÌ ¸Þ¼¼Áö Å¥ÀÇ ÀåÁ¡ÀÌ´Ù. Ä¿³ÎÀº ÀÚ·á°¡ ¹«¾ùÀ̵ç ÀÚ·áÀÇ º¯È¯À» ÀÏÀ¸Å°Áö ¾Ê´Â´Ù. ¾î¶² Á¤º¸µçÁö º¸³»Áú ¼ö ÀÖ´Ù. ÁÖ¾îÁø ¸Þ¼¼ÁöÀÇ ÃÖ´ë Å©±â¿¡ ´ëÇÑ ³»ºÎÀûÀÎ Á¦ÇÑÀº ¾ø´Ù. ¸®´ª½º¿¡¼­´Â linux/msg.h¿¡ ´ÙÀ½°ú °°ÀÌ Á¤ÀǵǾî ÀÖ´Ù.: {{{#!vim c #define^IMSGMAX^I4056^I/* <= 4056 */^I/* max size if message (bytes) ¸Þ¼¼ÁöÀÇ ÃÖ´ë Å©±â */ }}} ¸Þ¼¼Áö´Â ±æÀÌ°¡ 4¹ÙÀÌÆ®(long)ÀÎ mtype ¸â¹ö¸¦ Æ÷ÇÔÇÏ¿© ÃÑ Å©±â 4,056¹ÙÀÌÆ®º¸´Ù Ŭ ¼ö ¾ø´Ù. '''''Ä¿³Î msg ±¸Á¶ (Kernel msg structure)''''' ---- Ä¿³ÎÀº °¢°¢ÀÇ ¸Þ¼¼Áö¸¦ msg ±¸Á¶Ã¼ÀÇ ¸ð¾ÓÀ¸·Î Å¥¾È¿¡ ÀúÀåÇÑ´Ù. ÀÌ°ÍÀº linux/msg.h¿¡ ´ÙÀ½°ú °°ÀÌ Á¤ÀǵǾî ÀÖ´Ù. {{{#!vim c /* °¢ ¸Þ¼¼Áö¿¡ ´ëÇÑ ÇÑ°³ÀÇ ¸Þ¼¼Áö ±¸Á¶Ã¼ */ struct msg { struct^Imsg *msg_next;^I/* Å¥¿¡¼­ÀÇ ´ÙÀ½ ¸Þ¼¼Áö */ long msg_type; char *msg_spot; /* ¸Þ¼¼Áö ³»¿ë ÁÖ¼Ò */ short msg_ts; /* ¸Þ¼¼Áö ³»¿ë Å©±â */ }; }}} msg_next ÀÌ°ÍÀº Å¥¾È¿¡¼­ÀÇ ´ÙÀ½ ¸Þ¼¼Áö¿¡ ´ëÇÑ Æ÷ÀÎÅÍÀÌ´Ù. ÀÌ°ÍÀº Ä¿³ÎÀÇ ÁּҸŰÜÁø °ø°£ (kernel addressing space)¾È¿¡ ÇÑÁÙ·Î ¿¬°áµÈ ¸ñ·Ï(singly linked list)ó·³ ÀúÀåµÇ¾î ÀÖ´Ù. '''msg_type''' ÀÌ°ÍÀº »ç¿ëÀÚ ±¸Á¶Ã¼ÀÎ msgbuf¿¡ ÇÒ´çµÈ ¸Þ¼¼Áö ŸÀÔÀÌ´Ù. '''msg_spot''' ¸Þ¼¼Áö º»Ã¼ÀÇ ½ÃÀÛÁ¡À» °¡¸®Å°´Â Æ÷ÀÎÅÍ '''msg_ts''' ¸Þ¼¼Áö ³»¿ë ¶Ç´Â º»Ã¼ÀÇ ±æÀÌ '''''Ä¿³Î msqid ds ±¸Á¶ (Kernel msqid ds structure)''''' ---- IPC °´Ã¼ÀÇ ¼¼°¡Áö ŸÀÔÀÇ °¢°¢Àº Ä¿³Î¿¡ ÀÇÇØ À¯ÁöµÇ´Â ³»ºÎ ÀÚ·á ±¸Á¶¸¦ °¡Áø´Ù. ¸Þ¼¼Áö Å¥¿¡¼­´Â msq_id ±¸Á¶ÀÌ´Ù. Ä¿³ÎÀº ½Ã½ºÅÛ »ó¿¡¼­ »ý¼ºµÇ´Â ¸ðµç ¸Þ¼¼Áö Å¥¿¡ ´ëÇØ ÀÌ·¯ÇÑ ±¸Á¶¸¦ Çϳª¾¿ ¸¸µé¾î ÀúÀåÇÏ°í °ü¸®ÇÑ´Ù. linux/msg.h¿¡ ´ÙÀ½°ú °°ÀÌ Á¤ÀǵǾî ÀÖ´Ù.: {{{#!vim c /* ½Ã½ºÅÛ»ó¿¡¼­ °¢ Å¥¿¡ ´ëÇÑ msqid ±¸Á¶ */ struct msqid_ds { struct ipc_perm msg_perm; struct msg *msg_first; /* first message on queue Å¥ÀÇ Ã³À½ ¸Þ¼¼Áö*/ struct msg *msg_last; /* last message in queue Å¥ÀÇ ¸¶Áö¸· ¸Þ¼¼Áö*/ time_t msg_stime; /* last msgsnd time ¸¶Áö¸·À¸·Î msgsnd°¡ ¼öÇàµÈ ½Ã°£*/ time_t msg_rtime; /* last msgrcv time ¸¶Áö¸·À¸·Î msgrcv°¡ ¼öÇàµÈ ½Ã°£*/ time_t msg_ctime; /* last change time ¸¶Áö¸·À¸·Î change°¡ ¼öÇàµÈ ½Ã°£*/ struct wait_queue *wwait; struct wait_queue *rwait; ushort msg_cbytes; ushort msg_qnum; ushort msg_qbytes; /* max number of bytes on queue Å¥ÀÇ ÃÖ´ë ¹ÙÀÌÆ® ¼ö*/ ushort msg_lspid; /* pid of last msgsnd ¸¶Áö¸·À¸·Î msgsnd¸¦ ¼öÇàÇÑ pid*/ ushort msg_lrpid; /* last receive pid ¸¶Áö¸·À¸·Î ¹ÞÀº pid*/ }; }}} ÀÌ ±¸Á¶Ã¼ÀÇ ´ëºÎºÐÀÇ ¸â¹öµé¿¡ ´ëÇØ °ü½ÉÀ» °®´Â ÀÏÀº °ÅÀÇ ¾øÁö¸¸, ¿ì¸®µéÀÇ ¿©ÇàÀ» ¿Ï¼º½ÃÅ°±â À§ÇØ °¢°¢¿¡ ´ëÇØ °£´ÜÈ÷ ¼³¸íÇÏ°Ú´Ù. '''msg_perm''' ipc_perm ±¸Á¶Ã¼ÀÇ Çϳª·Î linux/ipc.h¿¡ Á¤ÀǵǾî ÀÖ´Ù. ÀÌ°ÍÀº Á¢±Ù Çã°¡»çÇ×(access permissions)°ú Å¥ÀÇ »ý¼ºÀÚ(creator)¿¡ ´ëÇÑ Á¤º¸(uid, etc)¸¦ Æ÷ÇÔÇÏ´Â ¸Þ¼¼Áö Å¥ÀÇ Çã°¡»çÇ× Á¤º¸¸¦ °¡Áö°í ÀÖ´Ù. '''msg_first''' Å¥ÀÇ Ã¹¹ø° ¸Þ¼¼Áö¿Í ¿¬°áµÇ¾î ÀÖ´Ù.(the head of the list) '''msg_last''' Å¥ÀÇ ¸¶Áö¸· ¸Þ¼¼Áö¿Í ¿¬°áµÇ¾î ÀÖ´Ù.(the tail of the list) '''msg_stime''' Å¥¿¡ º¸³»Áø ¸¶Áö¸· ¸Þ¼¼ÁöÀÇ ½Ã°£ ±â·Ï(Timestamp) '''msg_rtime''' Å¥·Î ºÎÅÍ Á¶È¸µÈ ¸¶Áö¸· ¸Þ¼¼ÁöÀÇ ½Ã°£ ±â·Ï(Timestamp) '''msg_ctime''' Å¥¿¡¼­ ÀϾ ¸¶Áö¸· º¯È­(change)ÀÇ ½Ã°£ ±â·Ï(Timestamp) (more on this later) '''wwait''' and '''rwait''' Ä¿³ÎÀÇ ´ë±â Å¥(wait queue)¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ. ¸Þ¼¼Áö Å¥¿¡ ÀÖ´Â µ¿ÀÛÀÌ ÇÁ·Î¼¼½º°¡ sleep »óÅ·Πµé¾î°¡´Â °ÍÀ¸·Î °£ÁÖÇÒ ¶§ »ç¿ëµÈ´Ù. (i.e. Å¥°¡ °¡µæÂ÷¼­ ÇÁ·Î¼¼½º°¡ ¿­¸®±â(opening)¸¦ ±â´Ù¸®°í ÀÖ´Â °æ¿ì) '''msg_qnum''' ÇöÀç Å¥¿¡ µé¾î ÀÖ´Â ¸Þ¼¼ÁöÀÇ °¹¼ö '''msg_qbytes''' Å¥ »óÀÇ ÃÖ´ë ¹ÙÀÌÆ® ¼ö '''msg_lspid''' ¸¶Áö¸· ¸Þ¼¼Áö¸¦ º¸³½ ÇÁ·Î¼¼½ºÀÇ PID '''msg_lrpid''' ¸¶Áö¸· ¸Þ¼¼Áö¸¦ Á¶È¸ÇÑ ÇÁ·Î¼¼½ºÀÇ PID '''''Ä¿³Î ipc perm ±¸Á¶ (Kernel ipc perm structure)''''' ---- Ä¿³ÎÀº ipc_perm ŸÀÔÀÇ ±¸Á¶Ã¼ ¾È¿¡ IPC °´Ã¼ÀÇ Çã°¡»çÇ×(permission) Á¤º¸¸¦ ÀúÀåÇÑ´Ù. ¿¹¸¦ µé¸é, ¾Õ¿¡¼­ ¼³¸íÇÑ ¸Þ¼¼Áö Å¥ÀÇ ³»ºÎ ±¸Á¶¿¡¼­´Â msg_perm ¸â¹ö°¡ ÀÌ·± ŸÀÔÀÌ´Ù. linux/ipc.h ¾È¿¡ ´ÙÀ½°ú °°ÀÌ ¼±¾ðµÇ¾î ÀÖ´Ù.: {{{#!vim c struct ipc_perm { key_t key; ushort uid; /* owner euid and egid */ ushort gid; ushort cuid; /* creator euid and egid */ ushort cgid; ushort mode; /* access modes see mode flags below */ ushort seq; /* slot usage sequence number */ }; }}} À§ÀÇ ³»¿ëµîÀº ¸ðµÎ ¸í¹éÈ÷ ÀÚ±â Çؼ®ÀûÀÌ´Ù. °´Ã¼ÀÇ IPC Å°¸¦ °¡Áö°í ÀúÀåµÇ¾î ÀÖ´Â °ÍÀº ±× °´Ã¼ÀÇ »ý¼ºÀÚ(creator)¿Í ÁÖÀÎ(owner)¿¡ ´ëÇÑ Á¤º¸ÀÌ´Ù. (creator¿Í owner´Â ¼­·Î ´Ù¸¦ ¼ö ÀÖÀ½) 8Áø Á¢±Ù ¸ðµå(the octal access mode) ¶ÇÇÑ usigned shortÇüÅ·Π¿©±â¿¡ ÀúÀåµÇ¾î ÀÖ´Ù. ¸¶Áö¸·À¸·Î ''slot usage sequence'' ¹øÈ£°¡ ³¡¿¡ ÀúÀåµÇ¾î ÀÖ´Ù. ¸Å¹ø IPC °´Ã¼´Â ½Ã½ºÅÛ È£Ãâ (destroyed)À» °æÀ¯ÇÏ¿© ´ÝÈù´Ù. ÀÌ °ªÀº ½Ã½ºÅÛ ¾È¿¡ Á¸ÀçÇÒ ¼ö ÀÖ´Â IPC °´Ã¼ÀÇ ÃÖ´ë¼ö¿¡ ÀÇÇØ Áõ°¡µÈ´Ù. ÀÌ °ª¿¡ ´ëÇØ ¿ì¸®°¡ °ü½ÉÀ» °¡Á®¾ß Çϴ°¡? ¾Æ´Ï´Ù. '''NOTE''':''Richard StevensÀÇ '''UNIX Network Programming''' 125ÂÊ¿¡ ÀÌ ÁÖÁ¦¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ³»¿ë°ú ÀÌ°ÍÀÇ Á¸Àç¿Í µ¿ÀÛÀÇ º¸¾È ÀÌÀ¯µîÀÌ Àß ¼³¸íµÇ¾î ÀÖ´Ù.'' ===== ½Ã½ºÅÛ È£Ãâ:msgget() (SYSTEM CALL:msgget()) ===== »õ·Î¿î ¸Þ¼¼Áö Å¥¸¦ ¸¸µé±â À§ÇÏ¿© ¶Ç´Â Á¸ÀçÇϴ ť¿¡ Á¢±ÙÇϱâ À§ÇÏ¿©, msgget() ½Ã½ºÅÛ È£ÃâÀÌ »ç¿ëµÈ´Ù. {{{ SYSTEM CALL: msgget(); PROTOTYPE: int msgget ( key_t key, int msgflg ); RETURNS: ¼º°ø½Ã ¸Þ¼¼Áö Å¥ÀÇ È®ÀÎÀÚ(message queue identifier) -1 on error: errno = EACCESS (Á¢±Ù±ÇÇÑÀÌ ¾øÀ½) EEXIST (Å¥°¡ ÀÌ¹Ì Á¸ÀçÇÏ¿© ¸¸µé ¼ö ¾øÀ½) EIDRM (Å¥¿¡ »èÁ¦ Ç¥½Ã°¡ µÇ¾î ÀÖÀ½) ENOENT (Å¥°¡ Á¸ÀçÇÏÁö ¾ÊÀ½) ENOMEM (Å¥¸¦ ¸¸µé±â¿¡ ¸Þ¸ð¸®°¡ ºÎÁ·ÇÔ) ENOSPC (ÃÖ´ë Å¥ÀÇ °¹¼ö¸¦ ÃÊ°úÇÔ) NOTES: }}} msgget()ÀÇ Ã¹¹ø° ¾Æ±Ô¸ÕÆ®´Â Å°°ªÀÌ´Ù.(ftok()¸¦ È£ÃâÇÏ¿© ³Ñ°Ü¹ÞÀº °æ¿ì) ÀÌ Å°°ªÀº Ä¿³Î¾È¿¡ ÀÖ´Â ´Ù¸¥ ¸Þ¼¼Áö Å¥µé¿¡ ´ëÇØ Å°°ªÀÌ Á¸ÀçÇÏ´ÂÁö¸¦ ºñ±³ÇÑ´Ù. À̶§, ¿­±â(open)³ª Á¢±Ù(access) µ¿ÀÛÀº msgflg ¾Æ±Ô¸ÕÆ®ÀÇ ³»¿ë¿¡ µû¸¥´Ù. '''IPC_CREAT''' Ä¿³Î¾È¿¡ Á¸ÀçÇÏ´ÂÁö¸¦ È®ÀÎÇÑ ÈÄ Å¥¸¦ ¸¸µç´Ù. '''IPC_EXCL''' IPC_CREAT°¡ »ç¿ëµÉ ¶§, Å¥°¡ ÀÌ¹Ì Á¸ÀçÇÏ¸é ½ÇÆÐó¸®ÇÑ´Ù. IPC_CREAT°¡ È¥ÀÚ »ç¿ëµÇ¸é, msgget()´Â »õ·Ó°Ô »ý¼±µÈ ¸Þ¼¼Áö Å¥ÀÇ ¸Þ¼¼Áö Å¥ È®ÀÎÀÚ (the message queue identifier)¸¦ ¹ÝȯÇϰųª, °°Àº Å°°ªÀ» °¡Áö°í ÀÌ¹Ì Á¸ÀçÇϴ ťÀÇ È®ÀÎÀÚ¸¦ ¹ÝȯÇÑ´Ù. IPC_EXCLÀÌ IPC_CREAT¿Í ÇÔ²² »ç¿ëµÇ¸é, »õ·Î¿î Å¥°¡ ¸¸µé¾îÁö°Å³ª Å¥°¡ Á¸ÀçÇϸé -1¸¦ °¡Áö¸ç È£Ãâ¿¡ ½ÇÆÐÇÑ´Ù. IPC_EXCLÀº ±× ÀÚü·Î´Â ¾µ¸ð°¡ ¾øÁö¸¸, IPC_CREAT¿Í ÇÔ²² Á¶ÇյǾî Á¢±ÙÇϱâ À§ÇÑ Á¸ÀçÇÏÁö ¾Ê´Â Å¥¸¦ ¿©´Â(open) °ÍÀ» º¸ÀåÇϴµ¥ »ç¿ëµÉ ¼ö ÀÖ´Ù. IPC °´Ã¼´Â À¯´Ð½º ÆÄÀÏ ½Ã½ºÅÛ»óÀÇ ÆÄÀÏ Çã°¡»çÇ×ÀÇ ±â´É°ú ºñ½ÁÇÑ Çã°¡»çÇ×À» °¡Áö°í ÀÖÀ¸¹Ç·Î, ºÎ°¡ÀûÀÎ 8Áø ¸ðµå´Â ¸¶½ºÅ© ¾È¿¡ ORµÉ °ÍÀÌ´Ù! ¸Þ¼¼Áö Å¥¸¦ ¸¸µé°Å³ª ¿­±â À§ÇÑ ºü¸¥ wrapper ÇÔ¼ö¸¦ ¸¸µé¾î º¸ÀÚ: {{{#!vim c int open_queue(key_t keyval) { int qid; if((qid = msgget( keyval, IPC_CREAT | 0660 )) == -1) { return(-1); } return(qid); } }}} ¹¬½ÃÀûÀ¸·Î 0660ÀÇ Çã°¡»çÇ×(permission)À» »ç¿ëÇÔÀ» ÁÖ¸ñÇ϶ó. ÀÌ ÀÛÀº ÇÔ¼ö´Â ¸Þ¼¼Áö Å¥ È®ÀÎÀÚ (int)¸¦ ¹ÝȯÇϰųª ¿¡·¯½Ã -1À» ¹ÝȯÇÑ´Ù. Å° °ªÀº ¾Æ±Ô¸ÕÆ®·Î ³Ñ°ÜÁ®¾ß¸¸ ÇÑ´Ù. ===== ½Ã½ºÅÛ È£Ãâ:msgsnd() (SYSTEM CALL:msgsnd()) ===== Å¥ÀÇ È®ÀÎÀÚ¸¦ °¡Áö°í ÀÖÀ¸¸é, Å¥ »ó¿¡¼­ ¿©·¯°¡Áö µ¿ÀÛÀ» ¼öÇàÇÒ ¼ö ÀÖ´Ù. Å¥¿¡ ¸Þ¼¼Áö¸¦ Àü´ÞÇϱâ À§ÇØ msgsnd ½Ã½ºÅÛ È£ÃâÀ» »ç¿ëÇÑ´Ù.: {{{ SYSTEM CALL: msgsnd(); PROTOTYPE: int msgsnd ( int msqid, struct msgbuf *msgp, int msgsz, int msgflg ); RETURNS: 0 on success -1 on error: errno = EAGAIN (queue is full, and IPC_NOWAIT was asserted) EACCES (permission denied, no write permission) EFAULT (msgp address isn't accessable - invalid) EIDRM (The message queue has been removed) EINTR (Received a signal while waiting to write) EINVAL (Invalid message queue identifier, nonpositive message type, or invalid message size) ENOMEM (Not enough memory to copy message buffer) NOTES: }}} msgsndÀÇ Ã¹¹ø° ¾Æ±Ô¸ÕÆ®´Â ÀÌÀüÀÇ msgget È£Ãâ¿¡ ÀÇÇØ ¹ÝȯµÈ Å¥ È®ÀÎÀÚÀÌ´Ù. µÎ¹ø° ¾Æ±Ô¸ÕÆ®ÀÎ msgp´Â Àç¼±¾ðµÇ°í ÀûÀçµÈ ¸Þ¼¼Áö ¹öÆÛÀÇ Æ÷ÀÎÅÍÀÌ´Ù. msgsz ¾Æ±Ô¸ÕÆ®´Â ¸Þ¼¼Áö ŸÀÔÀÇ ±æÀÌ(4¹ÙÀÌÆ®)¸¦ Á¦¿ÜÇÑ ¸Þ¼¼ÁöÀÇ ¹ÙÀÌÆ® Å©±â¸¦ Æ÷ÇÔÇÑ´Ù. msgflg ¾Æ±Ô¸ÕÆ®´Â 0À¸·Î ÁöÁ¤µÉ ¼ö ÀÖ´Ù.(ignored), or: '''IPC_NOWAIT''' ¸Þ¼¼Áö Å¥°¡ °¡µæ áÀ¸¸é, ¸Þ¼¼Áö´Â Å¥¿¡ ¾º¿©Áú ¼ö ¾ø°í, ÅëÁ¦±Ç(control)Àº È£ÃâÇÑ ÇÁ·Î¼¼½º¿¡°Ô µ¹¾Æ°£´Ù. ÁöÁ¤µÇÁö ¾Ê¾ÒÀ¸¸é, È£ÃâÇÑ ÇÁ·Î¼¼½º´Â ¸Þ¼¼Áö°¡ ¾º¿©Áú ¼ö ÀÖÀ» ¶§±îÁö ±â´Ù¸± °ÍÀÌ´Ù. ¸Þ¼¼Áö¸¦ º¸³»´Â ¶Ç ´Ù¸¥ wrapper ÇÔ¼ö¸¦ ¸¸µé¾îº¸ÀÚ: {{{#!vim c int send_message( int qid, struct mymsgbuf *qbuf ) { int result, length; /* ±æÀÌ´Â ±âº»ÀûÀ¸·Î ±¸Á¶Ã¼ÀÇ Å©±â - mtypeÀÇ Å©±â ÀÌ´Ù. */ length = sizeof(struct mymsgbuf) - sizeof(long); if((result = msgsnd( qid, qbuf, length, 0)) == -1) { return(-1); } return(result); } }}} ÀÌ ÀÛÀº ÇÔ¼ö´Â ³Ñ°ÜÁø Å¥ È®ÀÎÀÚ(qid)¿¡ ÀÇÇØ °í¾ÈµÈ ¸Þ¼¼Áö Å¥¿¡ ³Ñ°ÜÁø ÁÖ¼Ò(qbuf)¿¡ ÀÖ´Â ¸Þ¼¼Áö¸¦ º¸³»·Á°í ÇÑ´Ù. ¿©±â ¿ì¸®°¡ Áö±Ý±îÁö °³¹ßÇÑ µÎ°³ÀÇ wrapper ÇÔ¼ö¸¦ È°¿ëÇÑ °£´ÜÇÑ Äڵ尡 ÀÖ´Ù.: {{{#!vim c #include #include #include #include main() { int qid; key_t msgkey; struct mymsgbuf { long mtype; /* ¸Þ¼¼Áö ŸÀÔ */ int request; /* ÀÛ¾÷ ¿äû ¹øÈ£ */ double salary; /* Á÷¿øÀÇ ±Þ¿© */ } msg; /* IPC Å° °ªÀ» ¹ß»ý½ÃŲ´Ù */ if(( qid = open_queue( mdgkey)) == -1) { perror("open_queue"); exit(1); } /* ÀÓÀÇÀÇ Å×½ºÆ® ÀڷḦ ¸Þ¼¼Áö¿¡ ÀûÀçÇÑ´Ù */ msg.mtype = 1; /* ¸Þ¼¼Áö ŸÀÔÀº ¾ç¼ö¿©¾ß ÇÑ´Ù */ msg.request = 1; /* ÀÚ·á ¿ä¼Ò #1 */ msg.salary = 1000.00; /* ÀÚ·á ¿ä¼Ò #2 (³ªÀÇ ¿¬°£ ±Þ¿©) */ /* »½ ³¯·Áº¸³½´Ù */ if((send_message( qid, &msg )) == -1) { perror("send_message"); exit(1); } } }}} ¸Þ¼¼Áö Å¥¸¦ ¸¸µé°í ¿¬ ÈÄ¿¡, ¸Þ¼¼Áö ¹öÆÛ¿¡ Å×½ºÆ®¿ë ÀڷḦ ÀûÀçÇϴµ¥ ±îÁö Çß´Ù. ''(ÀÌÁø Á¤º¸¸¦ º¸³»´Â °Í¿¡ ´ëÇÑ ¿ì¸®ÀÇ °üÁ¡À» ¼³¸íÇϱ⿡´Â ¹®ÀÚ ÀÚ·á°¡ ºÎÁ·ÇßÀ½À» ÁÖ¸ñÇ϶ó)'' ºü¸¥ send_messageÀÇ È£ÃâÀº ´Ü¼øÈ÷ ¸Þ¼¼Áö¸¦ ¸Þ¼¼Áö Å¥·Î ºÐ¹èÇÑ´Ù. ÇöÀç ¿ì¸®´Â Å¥¿¡ ¸Þ¼¼Áö¸¦ °¡Áö°í ÀÖÀ¸¸ç, Å¥ÀÇ »óŸ¦ º¸±âÀ§ÇØ ipcs ¸í·É¾î¸¦ »ç¿ëÇضó. Å¥·Î ºÎÅÍ ½ÇÁ¦·Î ¸Þ¼¼Áö¸¦ Á¶È¸Çϱâ À§ÇÑ Åä·Ð¿¡ µé¾î°¡ º¸ÀÚ. ±×·± ÀÏÀ» ÇϱâÀ§ÇØ msgrcv() ½Ã½ºÅÛ È£ÃâÀ» »ç¿ëÇÑ´Ù.: {{{ SYSTEM CALL: msgrcv(); PROTOTYPE: int msgrcv ( int msqid, struct msgbuf *msgp, int msgsz, long mtype, int msgflg ); RETURNS: Number of bytes copied into message buffer -1 on error: errno = E2BIG (Message length is greater than msgsz, no MSG_NOERROR) EACCES (No read permission) EFAULT (Address pointed to by msgp is invalid) EIDRM (Queue was removed during retrieval) EINTR (Interrupted by arriving signal) EINVAL (msgqid invalid, or msgsz less than 0) ENOMSG (IPC_NOWAIT asserted, and no message exists in the queue to satisfy the request) NOTES: }}} ¸í¹éÇÏ°Ô, ù¹ø° ¾Æ±Ô¸ÕÆ®´Â ¸Þ¼¼Áö Á¶È¸ 󸮸¦ ÇÏ´Â µ¿¾È »ç¿ëµÉ Å¥¸¦ ÁöÁ¤Çϴµ¥ »ç¿ëµÈ´Ù. (ÀÏÂïÀÌ msgget¸¦ È£ÃâÇÏ¿© ¹ÝȯµÈ °ÍÀÌ¿©¾ß ÇÔ) µÎ¹ø° ¾Æ±Ô¸ÕÆ®(msgp)´Â Á¶È¸µÈ ¸Þ¼¼Áö¸¦ ÀúÀåÇÒ ¸Þ¼¼Áö ¹öÆÛ º¯¼öÀÇ ÁÖ¼Ò¸¦ ³ªÅ¸³½´Ù. ¼¼¹ø° ¾Æ±Ô¸ÕÆ®(msgsz)´Â mtype ¸â¹öÀÇ ±æÀ̸¦ Á¦¿ÜÇÑ ¸Þ¼¼Áö ¹öÆÛ ±¸Á¶Ã¼ÀÇ Å©±â¸¦ ³ªÅ¸³½´Ù. ´Ù½Ã Çѹø ´ÙÀ½Ã³·³ ½±°Ô °è»êµÉ ¼ö ÀÖ´Ù.: {{{#!vim c msgsz = sizeof(struct mymsgbif) - sizeof(long); }}} ³×¹ø° ¾Æ±Ô¸ÕÆ®(mtype)´Â Å¥·Î ºÎÅÍ Á¶È¸µÉ ¸Þ¼¼ÁöÀÇ Å¸ÀÔÀ» ÁöÁ¤ÇÑ´Ù. Ä¿³ÎÀº ŸÀÔ°ú ¸ÅĪµÇ´Â °¡Àå ¿À·¡µÈ ¸Þ¼¼Áö¸¦ Å¥¿¡¼­ ãÀ» °ÍÀÌ°í msgp ¾Æ±Ô¸ÕÆ®¿¡ ÀÇÇØ ÁöÀûµÈ ÁÖ¼Ò¿¡ ±×°ÍÀ» º¹»çÇÏ¿© ¹ÝȯÇÒ °ÍÀÌ´Ù. ÇÑ°¡Áö Ưº°ÇÑ °æ¿ì°¡ Á¸ÀçÇÑ´Ù. mtype ¾Æ±Ô¸ÕÆ®¿¡ 0 °ªÀÌ ³Ñ¾î¿À¸é, ŸÀÔÀ» ¹«½ÃÇÏ°í Å¥¿¡¼­ °¡Àå ¿À·¡µÈ ¸Þ¼¼Áö¸¦ ¹ÝȯÇÑ´Ù. '''IPC_NOWAIT'''°¡ flagó·³ ³Ñ°ÜÁö°í ÀÌ¿ë°¡´ÉÇÑ ¸Þ¼¼Áö°¡ ¾øÀ¸¸é, È£ÃâÇÑ ÇÁ·Î¼¼½º¿¡°Ô ENOMSG¸¦ ¹ÝȯÇÑ´Ù. ±×·¸Áö ¾ÊÀ¸¸é, È£ÃâÇÑ ÇÁ·Î¼¼½º´Â msgrcv() Æĸ®¹ÌÅ͸¦ ¸¸Á·½ÃÅ°´Â ¸Þ¼¼Áö°¡ Å¥¿¡ µµÂøÇÒ ¶§±îÁö ±â´Ù¸°´Ù. Ŭ¶óÀ̾ðÆ®°¡ ¸Þ¼¼Áö¸¦ ±â´Ù¸®°í ÀÖ´Â µ¿¾È Å¥°¡ Áö¿öÁö¸é, EIDRMÀÌ ¹ÝȯµÈ´Ù. ÇÁ·Î¼¼½º°¡ Â÷´Ü »óÅ¿¡ Àְųª ¸Þ¼¼Áö°¡ µµÂøÇϱ⸦ ±â´Ù¸®´Â µ¿¾È ½ÅÈ£°¡ ÀâÈ÷¸é, EINTR°¡ ¹ÝȯµÈ´Ù. Å¥·Î ºÎÅÍ ¸Þ¼¼Áö¸¦ Á¶È¸ÇÏ´Â ºü¸¥ wrapper ÇÔ¼ö¸¦ Á¡°ËÇØ º¸ÀÚ.: {{{#!vim c int read_message( int qid, long type, struct mymsgbuf *qbuf ) { int result, length; /* Å©±â´Â ±âº»ÀûÀ¸·Î ±¸Á¶Ã¼ÀÇ Å©±â - mtypeÀÇ Å©±â ÀÌ´Ù. */ length = sizeof(struct mymsgbuf) - sizeof(long); if((result = msgrcv( qid, qbuf, length, type, 0)) == -1) { return(-1); } return(result); } }}} Å¥·Î ºÎÅÍ ¸Þ¼¼ÁöÀÇ Á¶È¸°¡ ¼º°øÀûÀ¸·Î ÀÌ·ç¾îÁö¸é, Å¥ ¾È¿¡ ÀÖ´Â ¸Þ¼¼Áö´Â Æı«µÈ´Ù. msgflg ¾Æ±Ô¸ÕÆ® ¾ÈÀÇ '''MSG_NOERROR''' ºñÆ®´Â ¸î¸îÀÇ ºÎ°¡ÀûÀÎ ´É·ÂÀ» Á¦°øÇÑ´Ù. ¹°¸®ÀûÀÎ ¸Þ¼¼Áö ÀÚ·áÀÇ Å©±â°¡ msgszº¸´Ù Å©°í '''MSG_NOERROR'''°¡ »ç¿ëµÇ¸é, ¸Þ¼¼Áö´Â Àß·ÁÁ® ¿ÀÁ÷ msgsz ¹ÙÀÌÆ®¸¸Å­¸¸ ¹ÝȯµÈ´Ù. ÀϹÝÀûÀ¸·Î msgrcv() ½Ã½ºÅÛ È£ÃâÀº -1('''E2BIG''')À» ¹ÝȯÇÏ°í ´ÙÀ½ÀÇ Á¶È¸¸¦ À§ÇØ Å¥ »ó¿¡ ¸Þ¼¼Áö¸¦ ³²°Ü ³õ´Â´Ù. ÀÌ·± µ¿ÀÛÀº ¿ì¸®ÀÇ ¿äû¿¡ ¸¸Á·ÇÏ´Â ¸Þ¼¼Áö°¡ µµÂøÇß´ÂÁö¸¦ ¾Ë¾Æº¸±â À§ÇØ ¿ì¸®°¡ Å¥ ¾ÈÀ» ¿³º¼(peek) ¼ö ÀÖ´Â ¶Ç ´Ù¸¥ wrapper ÇÔ¼ö¸¦ ¸¸µé¾î »ç¿ëÇÒ ¼ö ÀÖ´Ù. {{{#!vim c int peek_message( int qid, long type ) { int result, length; if((result = msgrcv( qid, NULL, 0, type, IPC_NOWAIT)) == -1) { if(errno == E2BIG) return(TRUE); } return(FALSE); } }}} À§¿¡¼­ ´ç½ÅÀº ¹öÆÛÀÇ ÁÖ¼Ò¿Í ±æÀÌ°¡ ºÎÁ·ÇÔÀ» ¾Ë °ÍÀÌ´Ù. ÀÌ·± Ưº°ÇÑ °æ¿ì¿¡ À־, ¿ì¸®´Â È£ÃâÀÌ ½ÇÆÐÇϱ⸦ ¿øÇÑ´Ù. ±×·¸Áö¸¸ ¿ì¸®´Â ¿ì¸®°¡ ¿äûÇÑ Å¸ÀÔ°ú ÀÏÄ¡µÇ´Â ¸Þ¼¼Áö°¡ Á¸ÀçÇÏ´ÂÁö¸¦ ³ªÅ¸³»´Â '''E2BIG'''ÀÇ ¹ÝȯÀ» È®ÀÎÇÑ´Ù. wrapper ÇÔ¼ö´Â ¼º°øÇϸé '''TRUE'''¸¦, ±×·¸Áö¾ÊÀ¸¸é '''FALSE'''¸¦ ¹ÝȯÇÑ´Ù. ¶ÇÇÑ ÀÌÀü¿¡ ¾ð±ÞÇß´ø Â÷´Ü µ¿ÀÛ(Blocking behavior)À» ¸·±âÀ§ÇÑ '''IPC_NOWAIT''' flagÀÇ »ç¿ë¿¡ ÁÖ¸ñÇ϶ó. ===== ½Ã½ºÅÛ È£Ãâ:msgctl() (SYSTEM CALL:msgctl()) ===== ÀÌÀü¿¡ wrapper ÇÔ¼öµéÀÇ °³¹ßÀÌ Á¦°øµÇ¾úÁö¸¸, ÀÀ¿ëÇÁ·Î±×·¥¿¡¼­ ¸Þ¼¼Áö Å¥¸¦ ¸¸µé°í, È°¿ëÇϱâ À§ÇÑ °£´ÜÇÏ°í ¿ì¾ÆÇÑ Á¢±Ù¹æ¹ýÀ» °¡Áö°í ÀÖ´Ù. ÁÖ¾îÁø ¸Þ¼¼Áö Å¥¿Í ¿¬°üµÈ ³»ºÎ ±¸Á¶Ã¼¸¦ Á÷Á¢ Á¶Á¾Çϱâ À§ÇÑ Åä·Ð¿¡ µé¾î°¡ º¸ÀÚ. ¸Þ¼¼Áö Å¥ÀÇ ÅëÁ¦ µ¿ÀÛÀ» ¼öÇàÇϱâ À§ÇØ, msgctl() ½Ã½ºÅÛ È£ÃâÀ» »ç¿ëÇÑ´Ù. {{{ SYSTEM CALL: msgctl(); PROTOTYPE: int msgctl ( int msgqid, int cmd, struct msqid_ds *buf ); RETURNS: 0 on success -1 on error: errno = EACCES (No read permission and cmd is IPC_STAT) EFAULT (Address pointed to by buf is invalid with IPC_SET and IPC_STAT commands) EIDRM (Queue was removed during retrieval) EINVAL (msgqid invalid, or msgsz less than 0) EPERM (IPC_SET or IPC_RMID command was issued, but calling process does not have write (alter) access to the queue) NOTES: }}} ³»ºÎ Ä¿³Î ÀÚ·á ±¸Á¶ÀÇ Á÷Á¢ÀûÀÎ Á¶Á¾Àº ¹ã ´Êµµ·Ï Àç¹Ì¸¦ °¡Á®´Ù ÁÙ ¼öµµ ÀÖ´Ù. ºÒÇེ·´°Ôµµ, ÇÁ·Î±×·¡¸ÓµéÀÇ ÀϺο¡°Ô ³²°ÜÁø ÀÓ¹«´Â À⵿»ç´ÏÀÎ IPC subsystemÀ» ÁÁ¾ÆÇÑ´Ù¸é Àç¹Ì·Î ºÐ·ùµÇ¾î Áú ¼ö ÀÖ´Ù. ¼±ÅÃµÈ ¸í·É¾î ÁýÇÕÀ» °¡Áö°í msgctl()¸¦ »ç¿ëÇÏ¿©, Àç³­À» ÀÏÀ¸Å³ °¡´É¼ºÀÌ ÀûÀº ¾ÆÀÌÅÛÀ» Á¶Á¾ÇÒ ¼ö ÀÖ´Â ´É·ÂÀ» °®´Â´Ù. '''IPC_STAT''' Å¥¿¡¼­ msqid_ds ±¸Á¶Ã¼¸¦ Á¶È¸ÇÏ¿© ¹öÆÛ ¾Æ±Ô¸ÕÆ®ÀÇ ÁÖ¼ÒÁö¿¡ ÀúÀåÇÑ´Ù. '''IPC_SET''' Å¥ÀÇ msqid_ds ±¸Á¶Ã¼ÀÇ ipc_perm ¸â¹öÀÇ °ªÀ» ÁöÁ¤ÇÑ´Ù. ¹öÆÛ ¾Æ±Ô¸ÕÆ®·Î ºÎÅÍ °ªÀ» ÃëÇÑ´Ù. '''IPC_RMID''' Ä¿³Î·Î ºÎÅÍ Å¥¸¦ Á¦°ÅÇÑ´Ù. ¸Þ¼¼Áö Å¥¿¡ ´ëÇÑ ³»ºÎ ÀÚ·á ±¸Á¶(msqid_ds)¿¡ ´ëÇØ ¾ð±ÞÇß´ø ³»¿ëÀ» »ó±âÇÏÀÚ. Ä¿³ÎÀº ½Ã½ºÅÛ¿¡ Á¸ÀçÇÏ´Â °¢°¢ÀÇ Å¥¿¡ ´ëÇØ ÀÌ·¯ÇÑ ±¸Á¶Ã¼¸¦ Çϳª¾¿ °¡Áö°í ÀÖ´Ù. '''IPC_STAT''' ¸í·É¾î¸¦ »ç¿ëÇÏ¿© °Ë»ç¸¦ À§ÇØ ÀÌ ±¸Á¶Ã¼ÀÇ º¹»çº»À» Á¶È¸ÇÒ ¼ö ÀÖ´Ù. ³»ºÎ ±¸Á¶¸¦ Á¶È¸ÇÏ¿© ³Ñ°ÜÁø ÁÖ¼Ò·Î º¹»çÇÏ´Â ºü¸¥ wrapper ÇÔ¼ö¸¦ »ìÆ캸ÀÚ.: {{{#!vim c int get_queue_ds( int qid, struct msgqid_ds *qbuf ) { if( msgctl( qid, IPC_STAT, qbuf) == -1) { return(-1); } return(0); } }}} ³»ºÎ ¹öÆÛ·Î º¹»çÇÒ ¼ö ¾ø´Ù¸é È£ÃâÇÑ ÇÔ¼ö¿¡°Ô -1ÀÌ ¹ÝȯµÈ´Ù. ¸ðµç °ÍÀÌ Àß µÇ¸é, 0°ªÀÌ ¹ÝȯµÇ°í ³Ñ°ÜÁø ¹öÆÛ´Â ³Ñ°Ü¹ÞÀº Å¥ È®ÀÎÀÚ(queue identifier,qid)¿¡ ÀÇÇØ ´ëÇ¥µÇ´Â ¸Þ¼¼Áö Å¥¿¡ ´ëÇÑ ³»ºÎ ÀÚ·á ±¸Á¶ÀÇ º¹»çº»À» °®´Â´Ù. Å¥ÀÇ ³»ºÎ ÀÚ·á ±¸Á¶Ã¼ÀÇ º¹»çº»À» °¡Áö°í ÀÖÀ» ¶§, ¾î¶² Ư¼ºÀ» Á¶Á¾ÇÒ ¼ö ÀÖ°í, ±×°ÍµéÀ» ¾î¶»°Ô º¯°æ½Ãų ¼ö Àִ°¡? ÀÚ·á ±¸Á¶ ¾È¿¡¼­ ¿ÀÁ÷ ¼öÁ¤ÇÒ ¼ö ÀÖ´Â ¾ÆÀÌÅÛÀº ipc_perm ¸â¹öÀÌ´Ù. ÀÌ°ÍÀº ÁÖÀÎ(owner)¿Í »ý¼ºÀÚ(creator)¿¡ ´ëÇÑ Á¤º¸´Â ¹°·Ð, Å¥ÀÇ Çã°¡»çÇ×µµ Æ÷ÇÔÇÑ´Ù. ±×·¸Áö¸¸ ¼öÁ¤µÉ ¼öÀÖ´Â ipc_perm ±¸Á¶Ã¼ÀÇ ¸â¹öµéÀº mode,uid,gid »ÓÀÌ´Ù. ÁÖÀÎ(owner)ÀÇ user id, ÁÖÀÎ(owner)ÀÇ group id, Å¥ÀÇ Á¢±Ù Çã°¡»çÇ×(access permission)À» ¹Ù²Ü ¼ö ÀÖ´Ù. Å¥ÀÇ ¸ðµå(mode)¸¦ ¹Ù²Ùµµ·Ï °í¾ÈµÈ wrapper ÇÔ¼ö¸¦ ¸¸µé¾î º¸ÀÚ. ¸ðµå(mode)´Â ¹®ÀÚ ¹è¿­·Î ³Ñ°ÜÁ®¾ß ÇÑ´Ù (i.e. "660"). {{{#!vim c int change_queue_mode( int qid, char *mode ) { struct msqid_ds tmpbuf; /* ³»ºÎ ÀÚ·á ±¸Á¶ÀÇ ÇöÀç º¹»çº»À» Á¶È¸ÇÑ´Ù */ get_queue_ds( qid, &tmpbuf); /* ¿¾³¯ÀÇ ±â±³¸¦ »ç¿ëÇÏ¿© Çã°¡»çÇ×(permission)À» ¼öÁ¤ÇÑ´Ù */ sscanf(mode, "%ho", &tmpbuf.msg_perm.mode); /* ³»ºÎ ÀÚ·á ±¸Á¶¸¦ ¼öÁ¤ÇÑ´Ù */ if( msgctl( qid, IPC_SET, &tmpbuf) == -1) { return(-1); } return(0); } }}} get_queue_ds wrapper ÇÔ¼ö¸¦ °£´ÜÈ÷ È£ÃâÇÏ¿© ³»ºÎ ÀÚ·á ±¸Á¶ÀÇ ÇöÀç º¹»çº»À» Á¶È¸ÇÑ´Ù. ¿¬°üµÈ msg_perm ±¸Á¶ÀÇ mode ¸â¹ö¸¦ º¯°æÇϱâ À§ÇØ sscanf()¸¦ È£ÃâÇÑ´Ù. »õ º¹»çº»À» ³»ºÎ ¹öÀü¿¡ ¾÷µ¥ÀÌÆ®Çϱâ Àü¿¡´Â ¾Æ¹«·± º¯È­µµ ÀϾÁö ¾Ê´Â´Ù. ÀÌ·¯ÇÑ ÀÏÀº '''IPC_SET''' ¸í·É¾î¸¦ »ç¿ëÇÏ¿© msgctl()¸¦ È£ÃâÇÏ¿© ¼öÇàÇÒ ¼ö ÀÖ´Ù. ''ÁÖÀÇ!'' Å¥ÀÇ Çã°¡»çÇ×À» º¯°æÇÒ ¼ö ÀÖ°í, ±×·¸°Ô Çؼ­ º»ÀÇ¾Æ´Ï°Ô ½º½º·Î¸¦ Â÷´Ü½Ãų ¼ö ÀÖ´Ù. ±â¾ïÇ϶ó, ÀÌ·¯ÇÑ IPC °´Ã¼µéÀº Àû´çÈ÷ Á¦°ÅÇϰųª ½Ã½ºÅÛÀ» ÀçºÎÆÃÇÏÁö ¾ÊÀ¸¸é ¾ø¾îÁöÁö ¾Ê´Â´Ù. µû¶ó¼­ ipcs¸¦ °¡Áö°í Å¥¸¦ º¼ ¼ö ¾ø´Ù°í ÇÏ¿© Á¸ÀçÇÏÁö ¾Ê´Â´Ù´Â °ÍÀ» ÀǹÌÇÏÁö´Â ¾Ê´Â´Ù. ÀÌ Á¡À» ¼³¸íÇϱâ À§ÇØ, ´Ù¼Ò Àç¹ÌÀÖ´Â ÀÏÈ­¸¦ ¼Ò°³ÇÏ°Ú´Ù. South Florida ´ëÇп¡¼­ À¯´Ð½º ³»ºÎ¸¦ °¡¸£Ä¡´Â µ¿¾È, ³ª´Â ¾ÆÁÖ ´çȲ½º·´°í ¾î¸®µÕÀýÇÑ Â÷´Ü(Blocking)¿¡ Á÷¸éÇß´Ù. Áö³­¹ã¿¡ ³ª´Â ÀÏÁÖÀÏ°£ÀÇ ¼ö¾÷¿¡¼­ »ç¿ëµÈ ¿¬±¸¹Ú¾÷À» Å×½ºÆ®ÇÏ°í ÄÄÆÄÀÏÇϱâ À§ÇØ ¿¬±¸½Ç ¼­¹ö¿¡ Á¢¼ÓÇß´Ù. Å×½ºÆ®¸¦ ÇÏ´Â µ¿¾È¿¡ ³ª´Â ÄÚµå¾È¿¡ ¸Þ¼¼Áö Å¥ÀÇ Çã°¡»çÇ×(permission)À» º¯°æÇϴ ŸÀÔÀ» ¸¸µé¾ú´Ù´Â »ç½ÇÀ» ±ú´Þ¾Ò´Ù. ³ª´Â °£´ÜÇÑ ¸Þ¼¼Áö Å¥¸¦ ¸¸µé¾ú°í, ¾Æ¹«·± »ç°í¾øÀÌ ÁÖ°í ¹ÞÀ» ¼ö ÀÖ´ÂÁö¸¦ Å×½ºÆ® Çß´Ù. ±×·¸Áö¸¸, ³»°¡ Å¥ÀÇ ¸ðµå¸¦ "660"¿¡»ç "600"À¸·Î ¼öÁ¤ÇÏ·Á°í ÇßÀ» ¶§, ³» ÀÚ½ÅÀÇ Å¥·Î ºÎÅÍ ³ª ÀÚ½ÅÀ» ¸·¾Æ¹ö¸®´Â °á°ú¸¦ ÃÊ·¡Çß´Ù. °á°úÀûÀ¸·Î ³ª´Â ³» ¼Ò½º µð·ºÅ丮ÀÇ °°Àº ¿µ¿ª¿¡¼­ ¸Þ¼¼Áö Å¥ ¿¬±¸ÀÛ¾÷À» Å×½ºÆ® ÇÒ ¼ö ¾ø¾ú´Ù. ³»°¡ IPC Å°¸¦ ¸¸µé±â À§ÇØ ftok() ÇÔ¼ö¸¦ »ç¿ëÇ߱⿡, ³»°¡ Å¥¿¡ Á¢±ÙÇÏ·Á°í ÇÒ ¶§ ³ª´Â Àû´çÇÑ Çã°¡»çÇ×(permission)À» °®°í ÀÖÁö ¸øÇß´Ù. ¼ö¾÷ÀÌ ÀÖ´Â ¾Æħ¿¡ °á±¹ ³ª´Â Áö¿ª ½Ã½ºÅÛ °ü¸®ÀÚ¿¡°Ô ¸Þ¼¼Áö Å¥°¡ ¹«¾ùÀÎÁö¿Í ¿Ö ±×°¡ ³ª¸¦ À§ÇØ ipcrm ¸í·É¾î¸¦ ¼öÇà½ÃÄÑ¾ß ÇÏ´ÂÁö¸¦ Çѽ𣵿¾È ¼³¸íÇÏ°í Á¢¼ÓÀ» ³¡³Â´Ù. Å¥·ÎºÎÅÍ ¼º°øÀûÀ¸·Î ¸Þ¼¼Áö¸¦ ¹ÞÀº ÈÄ, ¸Þ¼¼Áö´Â Á¦°ÅµÈ´Ù. ¾Õ¿¡¼­µµ ¾ð±ÞÇß´ø °Íó·³, IPC °´Ã¼´Â ¸í¹éÈ÷ Á¦°ÅµÇ°Å³ª ½Ã½ºÅÛÀ» ÀçºÎÆÃÇÏÁö ¾Ê´Â ÇÑ ½Ã½ºÅÛ¿¡ ³²¾Æ Àִ´Ù. ±×·¯¹Ç·Î, ¿ì¸®ÀÇ ¸Þ¼¼Áö Å¥´Â ¿©ÀüÈ÷ Ä¿³Î¾È¿¡ Á¸ÀçÇÏ°í ´ÜÀÏ ¸Þ¼¼Áö°¡ »ç¶óÁø ÈÄ¿¡µµ °è¼Ó »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¸Þ¼¼Áö Å¥ÀÇ »ý¸í ÁÖ±â(life cycle)¸¦ ¿Ï¼ºÇϱâ À§ÇØ '''IPC_RMID''' ¸í·É¾î¸¦ »ç¿ëÇÏ¿© msgctl()¸¦ È£Ãâ¿¡ ÀÇÇØ Á¦°ÅµÇ¾î¾ß ÇÑ´Ù.: {{{#!vim c int remove_queue( int qid ) { if( msgctl( qid, IPC_RMID, 0) == -1) { return(-1); } return(0); } }}} ÀÌ wrapper ÇÔ¼ö´Â Å¥°¡ »ç°í¾øÀÌ Á¦°ÅµÇ¸é 0À» ¹ÝȯÇÏ°í ¾Æ´Ï¸é -1À» ¹ÝȯÇÑ´Ù. Å¥ÀÇ Á¦°Å´Â ÀÚ¿¬ÀûÀ¸·Î atomicÇÏ°í ¾î¶² ¸ñÀû¿¡¼­°Ç Å¥¿¡ ´ëÇÑ ¾î¶² ÀÏ·ÃÀÇ Á¢±Ùµµ ÇüÆí¾øÀÌ ½ÇÆÐÇÒ °ÍÀÌ´Ù. ===== msgtool:»óÈ£ÀÛ¿ë ¸Þ¼¼Áö Å¥ Á¶Á¾ÀÚ (An interactive message queue manipulator) ===== ½±°Ô ÀÌ¿ëÇÒ ¼ö ÀÖ´Â Á¤È®ÇÑ ±â¼úÀûÀÎ Á¤º¸¸¦ °®´Â Á÷Á¢ÀûÀÎ ÀÌÀÍÀ» ¼Ò¼öÀÇ »ç¶÷¸¸ÀÌ °¡Áø´Ù´Â °ÍÀº ºÎÀÎÇÒ ¼ö ¾ø´Ù. ¾î¶² ¿ä¼ÒµéÀº »õ·Î¿î ¿µ¿ªÀÇ ¹è¿ò°ú Ž±¸¸¦ À§ÇÑ ¸ÚÁø ±â±³(mechanism)¸¦ Á¦°øÇÑ´Ù. °°Àº ¸Æ¶ô¿¡¼­, ¾î¶² ±â¼úÀûÀÎ Á¤º¸¸¦ µû¸£´Â ½Ç¼¼°èÀÇ ¿¹Á¦¸¦ °¡Áö´Â °ÍÀº ÇÁ·Î¼¼½º¸¦ ¹è¿ì´Â °ÍÀ» »¡¸®ÇÏ°í °­È­½Ãų °ÍÀÌ´Ù. Áö±Ý±îÁö, ¾ð±ÞµÈ À¯¿ëÇÑ ¿¹Á¦µéÀº ¸Þ¼¼Áö Å¥¸¦ Á¶Á¾ÇÏ´Â wrapper ÇÔ¼öµéÀÌ¿´´Ù. ±×°ÍµéÀº ¸Å¿ì À¯¿ëÇÏÁö¸¸, ¾î¶² Àǹ̿¡¼­´Â º¸´Ù ´õ ±íÀº °øºÎ¿Í ½ÇÇèÀ» º¸ÀåÇÏÁö´Â ¸øÇÏ°í ÀÖ´Ù. ÀÌ·± Á¡À» °³¼±Çϱâ À§ÇØ, IPC ¸Þ¼¼Áö Å¥¸¦ Á¶Á¾Çϱâ À§ÇÑ msgtool, »óÈ£ÀÛ¿ë ¸í·É¾î ¶óÀÎ À¯Æ¿¸®Æ¼(interative command line utility)¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÀÌ°ÍÀº È®½ÇÈ÷ ±³À° °­È­¸¦ À§ÇÑ Àû´çÇÑ µµ±¸·Î¼­ÀÇ ±â´ÉÀ» ÇÏÁö¸¸, Ç¥ÁØ ½© ½ºÅ©¸³Æ®¸¦ °æÀ¯ÇÏ¿© ¸Þ¼¼Áö Å¥ ±â´ÉÀ» Á¦°øÇÏ´Â °Í¿¡ ÀÇÇØ ½Ç ¼¼°èÀÇ °úÁ¦¿¡ Á÷Á¢ Àû¿ëÇÒ ¼ö´Â ¾ø´Ù. '''''¹é±×¶ó¿îµå (Background)''''' ---- msgtool ÇÁ·Î±×·¥Àº ¸í·É¾î ¶óÀÎÀÇ ¾Æ±Ô¸ÕÆ®¿¡ ÀÇÇØ µ¿ÀÛÀÌ °áÁ¤µÈ´Ù. ÀÌ°ÍÀº ½© ½ºÅ©¸³Æ®·Î ºÎÅÍ È£ÃâµÇ¾îÁú ¶§, ¸Å¿ì À¯¿ëÇÏ°Ô »ç¿ëµÉ °ÍÀÌ´Ù. Å¥¸¦ ¸¸µé°í ¸Þ¼¼Áö¸¦ º¸³»°í Á¶È¸ÇÏ°í Å¥ÀÇ Çã°¡»çÇ×À» ¹Ù²Ù°í ³¡À¸·Î Á¦°ÅÇÏ´Â ¸ðµç ´É·ÂÀÌ Á¦°øµÈ´Ù. ÇöÀç, º»¹® »óÀÇ ¸Þ¼¼Áö¸¦ º¸³»´Âµ¥ Çã¿ëµÇ´Â µ¥ÀÌŸ·Î´Â ¹®ÀÚ ¹è¿­À» »ç¿ëÇÑ´Ù. ºÎ°¡ÀûÀÎ ÀÚ·á ŸÀÔÀ» ¿ëÀÌÇÏ°Ô ¹Ù²Ù´Â °ÍÀº µ¶ÀÚµéÀÇ °úÁ¦·Î ³²°ÜÁ® ÀÖ´Ù. '''''¸í·É¾î ¶óÀÎ ¹®¹ý (Command Line Syntax)''''' ---- '''¸Þ¼¼Áö º¸³»±â (Sending Messages)''' {{{ msgtool s (type) "text" }}} '''¸Þ¼¼Áö Á¶È¸Çϱâ (Retrieving Messages)''' {{{ msgtool r (type) }}} '''Çã°¡»çÇ× ¹Ù²Ù±â (Changing the Permissions(mode))''' {{{ msgtool m (mode) }}} '''Å¥ Áö¿ì±â (Deleting a Queue)''' {{{ msgtool d }}} '''''¿¹Á¦ (Examples)''''' ---- {{{ msgtool s 1 test msgtool s 5 test msgtool s 1 "This is a test" msgtool r 1 msgtool d msgtool m 660 }}} '''''¼Ò½º (The Source)''''' ---- ´ÙÀ½Àº msgtool »ç¿ëÀ» À§ÇÑ ¼Ò½º ÄÚµåÀÌ´Ù. ½Ã½ºÅÛ V IPC¸¦ Áö¿øÇÏ´Â ÃÖ½ÅÀÇ Ä¿³Î °³Á¤ÆÇ¿¡¼­ ±ú²ýÀÌ ÄÄÆÄÀϵǾî¾ß ÇÑ´Ù. ÀçÀÛ¼º(rebuild)½Ã Ä¿³Î¿¡¼­ ½Ã½ºÅÛ V IPC¸¦ »ç¿ëÇÒ ¼ö ÀÖ´ÂÁö È®ÀÎÇ϶ó. ÇÑÆíÀ¸·Î, ÀÌ À¯Æ¿¸®Æ¼´Â ¾î¶² µ¿ÀÛÀÌ ¿äûµÇµçÁö¿¡ »ó°ü¾øÀÌ ¸Þ¼¼Áö Å¥°¡ Á¸ÀçÇÏÁö ¾ÊÀ¸¸é ¸Þ¼¼Áö Å¥¸¦ ¸¸µé °ÍÀÌ´Ù. '''NOTE:''' ''ÀÌ ÅøÀº IPC Å° °ªÀ» ¹ß»ý½ÃÅ°±âÀ§ÇØ ftok()ÇÔ¼ö¸¦ »ç¿ëÇÔÀ¸·Î, µð·ºÅ丮 Ãæµ¹À» ¸¸³¯Áö ¸ð¸¥´Ù. ½ºÅ©¸³Æ® ³»ÀÇ ¾î´À ÇÑÁöÁ¡¿¡¼­ µð·ºÅ丮¸¦ ¹Ù²Û´Ù¸é, ¾Æ¸¶µµ µ¿ÀÛÇÏÁö ¾ÊÀ» °ÍÀÌ´Ù. ¶Ç ´Ù¸¥ ÇØ°áÃ¥Àº msgtool¾È¿¡ "/tmp/msgtool/"°ú °°ÀÌ º¸´Ù Àý´ëÀûÀÎ °æ·Î(path)¸¦ ÇϵåÄÚµùÇϰųª Á¶ÀÛ»ó(operational)ÀÇ ¾Æ±Ô¸ÕÆ®¿¡ µû¶ó, ¸í·É¾î ¶óÀλ󿡼­ ³Ñ°ÜÁø °æ·Î(path)¸¦ »ç¿ëÅä·Ï Çã¶ôÇÏ´Â °ÍÀÌ´Ù.'' {{{#!vim c /***************************************************************************** ¸®´ª½º ÇÁ·Î±×·¡¸Ó¸¦ À§ÇÑ °¡À̵å - 6Àå ¿¡¼­ ¹ßÃé (C)opyright 1994-1995, Scott Burkett ***************************************************************************** MODULE: msgtool.c ***************************************************************************** ½Ã½ºÅÛ V ½ºÅ¸ÀÏÀÇ ¸Þ¼¼Áö Å¥¸¦ »ç¿ëÇϱâ À§ÇÑ ¸í·É¾î ¶óÀÎ Åø *****************************************************************************/ #include #include #include #include #include #include #define MAX_SEND_SIZE 80 struct mymsgbuf { long mtype; char mtext[MAX_SEND_SIZE]; }; void send_message(int qid, struct mymsgbuf *qbuf, long type, char *text); void read_message(int qid, struct mymsgbuf *qbuf, long type); void remove_queue(int qid); void change_queue_mode(int qid, char *mode); void usage(void); int main(int argc, char *argv[]) { key_t key; int msgqueue_id; struct mymsgbuf qbuf; if(argc == 1) usage(); ^I/* ftok() È£ÃâÀ» ÅëÇØ À¯ÀÏÇÑ Å°¸¦ ¸¸µç´Ù */ key = ftok(".", 'm'); ^I/* ÇÊ¿äÇÏ´Ù¸é Å¥¸¦ ¸¸µé°í ¿¬´Ù */ if((msgqueue_id = msgget(key, IPC_CREAT|0660)) == -1) { perror("msgget"); exit(1); } switch(tolower(argv[1][0])) { case 's': send_message(msgqueue_id, (struct mymsgbuf *)&qbuf, atol(argv[2]), argv[3]); break; case 'r': read_message(msgqueue_id, &qbuf, atol(argv[2])); break; case 'd': remove_queue(msgqueue_id); break; case 'm': change_queue_mode(msgqueue_id, argv[2]); break; default: usage(); } return(0); } void send_message(int qid, struct mymsgbuf *qbuf, long type, char *text) { ^I/* Å¥¿¡ ¸Þ¼¼Áö¸¦ º¸³½´Ù */ printf("Sending a message ...\n"); qbuf->mtype = type; strcpy(qbuf->mtext, text); if((msgsnd(qid, (struct msgbuf *)qbuf, strlen(qbuf->mtext)+1, 0)) ==-1) { perror("msgsnd"); exit(1); } } void read_message(int qid, struct mymsgbuf *qbuf, long type) { ^I/* Å¥·Î ºÎÅÍ ¸Þ¼¼Áö¸¦ Àд´Ù. */ printf("Reading a message ...\n"); qbuf->mtype = type; msgrcv(qid, (struct msgbuf *)qbuf, MAX_SEND_SIZE, type, 0); printf("Type: %ld Text: %s\n", qbuf->mtype, qbuf->mtext); } void remove_queue(int qid) { ^I/* Å¥¸¦ Áö¿î´Ù */ msgctl(qid, IPC_RMID, 0); } void change_queue_mode(int qid, char *mode) { struct msqid_ds myqueue_ds; ^I/* ÇöÀç Á¤º¸¸¦ Àд´٠*/ msgctl(qid, IPC_STAT, &myqueue_ds); ^I/* ¸ðµå¸¦ Àоî¿Í ¹Ù²Û´Ù */ sscanf(mode, "%ho", &myqueue_ds.msg_perm.mode); ^I/* ¸ðµå¸¦ ¼öÁ¤ÇÑ´Ù */ msgctl(qid, IPC_SET, &myqueue_ds); } void usage(void) { fprintf(stderr, "msgtool - A utility for tinkering with msg queues\n"); fprintf(stderr, "\nUSAGE: msgtool (s)end \n"); fprintf(stderr, " (r)ecv \n"); fprintf(stderr, " (d)elete\n"); fprintf(stderr, " (m)ode \n"); exit(1); } }}} ---- It's seems that this document is rather too old... Ex) poll() system call has been supported in Linux for long time.