· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
About Linux

1.1. GNU/Linux ±¸Á¶

image02.png
[PNG image (1.87 KB)]
  • Linux´Â Kernel, Libc, ApplicationÀ¸·Î ±¸¼ºµÇ´Âµ¥ À̸¦ ÅëƲ¾î¼­ GNU/Linux ¶ó°í ºÎ¸¨´Ï´Ù.
  • GNU/Linux´Â Å©°Ô Kernel¿µ¿ª°ú User¿µ¿ªÀ¸·Î Á¢±Ù±ÇÇÑ¿¡ ÀÇÇØ ³ª´µ¾îÁý´Ï´Ù.
  • User¿µ¿ªÀ¸·ÎºÎÅÍ System Call Interface¿¡ ÀÇÇؼ­ Kernel¿µ¿ªÀÇ ÇÔ¼ö¸¦ È£ÃâÇÕ´Ï´Ù.
  • Kernel¿µ¿ª¿¡¼­´Â ¸ðµç ¹°¸®Àû ÀåÄ¡ÀÇ Á¢±ÙÁ¦¾î°¡ °¡´ÉÇÏÁö¸¸ User ¿µ¿ª¿¡¼­´Â Á÷Á¢ÀûÀÎ Á¢±Ù¿¡´Â ¸¹Àº Á¦¾àÀÌ ÀÖÀ¸¸ç User¿µ¿ª¿¡¼­ÀÇ ¹°¸®Àû ÀåÄ¡Á¢±ÙÀ» À§Çؼ­´Â Kernel¿µ¿ªÀ¸·Î SCI¸¦ ÅëÇؼ­ ¿äûÇÏ´Â ½ÄÀ¸·Î µ¿ÀÛÇÏ°Ô µË´Ï´Ù.
  • LibcºÎºÐÀº GNU C Library(glibc) °¡ °¡Àå ¸¹ÀÌ »ç¿ëµÇ°í Embedded ȯ°æ¿¡¼­´Â Å©±â°¡ ºñ±³Àû ÀÛÀº uClibc µîÀÌ ¸¹ÀÌ »ç¿ëµË´Ï´Ù.

1.2. Linux kernelÀÇ ±¸¼º¿ä¼Ò

image03.png
[PNG image (1.74 KB)]
  • Linux kernelÀº ±×¸²°ú °°ÀÌ ArchitectureÀÇÁ¸ÀûÀÎ ºÎºÐ, Device driverµé, Memory°ü¸®, Process ¹× Thread°ü¸®, °¡»óÆÄÀϽýºÅÛ, NetworkStack, SCI·Î ±¸¼ºµÇ¾î ÀÖ½À´Ï´Ù. Ä¿³ÎÀº ÀÌ·¯ÇÑ ÀÚ¿øÀ» »ç¿ëÀÚµéÀÇ ¿ä±¸¿¡ ´ëÇÏ¿© ÀûÀýÈ÷ ÁßÀçÇÏ¿© °ü¸®ÇÏ´Â ¿ªÇÒÀ» ´ã´çÇÕ´Ï´Ù.

1.3. Linux kernel imageÀÇ ±¸Á¶

image04.png
[PNG image (992 Bytes)]
  • BootsectorÀº Floppy boot µîÀ» À§ÇÑ boot sector code·Î ÀÌ·ç¾îÁý´Ï´Ù. º¸Åë Bootloader¿¡ ÀÇÇؼ­ ºÎÆÃÇÏ´Â °æ¿ì ÀÌ ºÎºÐÀº »ç¿ëÇÏÁö ¾Ê°Å³ª °Ç³Ê¶Ý´Ï´Ù.
  • SetupÀº ±âÃÊÀûÀÎ Memory ¼³Á¤À̳ª ¾ÐÃàÀ» Ç®±âÀ§ÇÑ »çÀü´Ü°è¸¦ ÁøÇàÇÏ´Â code·Î ÀÌ·ç¾îÁý´Ï´Ù. Bootloader¿¡ ÀÇÇؼ­ ºÎÆÃÇÏ´Â °æ¿ì Setup À¸·Î jump ÇÏ°Ô µË´Ï´Ù.
  • Head+Misc´Â ¾ÐÃàµÈ Kernel ¿µ¿ªÀ» ÇØÁ¦ÇÏ´Â codeµé·Î ÀÌ·ç¾îÁý´Ï´Ù.

1.4. VFS

image06.png
[PNG image (1.53 KB)]
  • LinuxÀÇ Æ¯Â¡Áß¿¡ ¼ö¸¹Àº ÆÄÀϽýºÅÛ¿¡ ´ëÇÏ¿© ¿©·¯°¡Áö InterfaceÃß»óÈ­¸¦ Á¦°ø ÇÑ´Ù´Â Á¡ÀÌ ÀÖ½À´Ï´Ù.
  • ÆÄÀϽýºÅÛµéÀº »ç¿ëÇÏÁö ¾Ê´Â ¸Þ¸ð¸®¸¦ È°¿ëÇÑ Buffer cacheÀÚ¿ø¿¡ µµ¿òÀ» ¹Þ¾Æ¼­ ¹°¸®Àû ÀúÀåÀåÄ¡ÀÇ Á¢±ÙÀ» ÃÖÀûÈ­ ÇÕ´Ï´Ù.
  • procfs, devfs, sysfsµî ¹°¸®Àû ÀúÀåÀåÄ¡°¡ ¾Æ´Ñ ¾î¶² Á¦¾î¸¦ ¸ñÀûÀ¸·Î ¸¸µé¾îÁø °¡»ó ÆÄÀϽýºÅÛµµ ÇϳªÀÇ ÆÄÀϽýºÅÛÀ¸·Î Ãë±ÞÇÕ´Ï´Ù.

1.4.1. Loopback ÀåÄ¡

½ÇÁ¦ µð¹ÙÀ̽º ÀåÄ¡¿Í µ¿ÀÏÇÏ°Ô µ¿ÀÛÇϵµ·Ï ÇÏÁö¸¸ ½ÇÁ¦·Î´Â ÇϳªÀÇ °¡»óÀåÄ¡¿¡ ¼ÓÇÏ´Â °ÍÀ» Loopback ÀåÄ¡¶ó°í ÇÕ´Ï´Ù.

ÇϳªÀÇ ÆÄÀÏ¿¡ ƯÁ¤ ÆÄÀϽýºÅÛÀÇ Çü½ÄÀ» °®Ãß¾î ÀúÀåÇÑÈÄ ÀÌ°ÍÀ» ÇϳªÀÇ ÀåÄ¡·Î º¸µµ·Ï ÇÏ¿© mount ÇÒ¼ö Àִµ¥ ÀÌ·¯ÇÑ °æ¿ì Loopback ÆÄÀϽýºÅÛÀ̶ó°í ÇÕ´Ï´Ù.

1.4.2. Ram-disk

Ưº°ÇÑ ÀúÀåÀåÄ¡°¡ ¾Æ´Ñ ¸Þ¸ð¸® ±× ÀÚü¸¦ ÀúÀåÀÇ ¿ëµµ·Î ÇϳªÀÇ µð½ºÅ©Ã³·³ »ç¿ëÇÒ¼ö ÀÖµµ·Ï ÇسõÀº°ÍÀ» Ram-DiskÀåÄ¡¶ó°í ÇÕ´Ï´Ù. ÀÌ°ÍÀº Loopback Àåġó·³ ƯÁ¤ ÆÄÀϽýºÅÛÀ¸·Î Æ÷¸ËÇÒ¼öµµ ÀÖ°í mountÇÒ¼öµµ ÀÖÀ¸¸ç ÀÏ¹Ý ÀúÀåÀåÄ¡º¸´Ù ¸Þ¸ð¸®¸¦ ÀÌ¿ëÇϱ⠶§¹®¿¡ ¸Å¿ì ºü¸¥ read/write/search°¡ °¡´ÉÇϴٴ°ÍÀÌ ÀåÁ¡ÀÌÁö¸¸ Àü¿øÀÌ ²¨Áö¸é ±× ÀÚ·áµµ ³¯¾Æ°£´Ù´Â Á¡ÀÌ ´ÜÁ¡À̶ó°í ÇÒ¼ö ÀÖ½À´Ï´Ù.

ºÎÆýÿ¡´Â Loopback ÀåÄ¡·Î ÀνÄÇÏ´Â Initial ram-disk¸¦ rootfsÀ¸·Î ÇÏ¿© º¹ÀâÇÑ ºÎÆÿ䱸Á¶°ÇÀ» ÇØ°áÇϱ⵵ ÇÕ´Ï´Ù.

1.5. Process°£ÀÇ Åë½ÅÁö¿ø

°¡) Signal : Á¤ÀÇµÈ À̺¥Æ®¸¦ ºñµ¿±âÀûÀ¸·Î ¾Ë¸®±â À§Çؼ­ »ç¿ëÇÕ´Ï´Ù. ³ª) Pipe : VFS inode¸¦ ÀÌ¿ëÇÑ Åë½Å¹æ½ÄÀÔ´Ï´Ù. ÀÌ´Â redirectionµî¿¡ ¸¹ÀÌ »ç¿ëµË´Ï´Ù. ´Ù) Socket : NetworkÅë½ÅÀ» À§ÇÑ ÀÚ¿øÀÔ´Ï´Ù. ´ëºÎºÐ BSD socket interface¸¦ ÅëÇؼ­ ±¸ÇöµË´Ï´Ù. ¶ó) System V IPC : MessageQueue, Semaphore, Shared memoryµîÀÌ IPCÀÚ¿øÀ» ÅëÇؼ­ ±¸ÇöµË´Ï´Ù.

1.6. Memory ÇÒ´çü°è

Kernel¿¡¼­ÀÇ memoryÇÒ´çÀº Virtual alloc°ú Physical allocÀÌ ¼ö¹ÝµÇ¸ç ÇÒ´çÇÔ¼ö´Â Å©°Ô ¿¬¼ÓÀûÀÎ ¹°¸®°ø°£À» È®º¸Çϱâ À§ÇÑ ÇÔ¼ö¿Í ±×·¸Áö ¾Ê¾Æµµ µÇ´Â ÇÔ¼ö·Î ºÐ·ùµÉ¼ö ÀÖ½À´Ï´Ù.

  • Contiguous allocation
    • get_free_pages : Buddy¾Ë°í¸®Áò¿¡ ÀÇÇÑ ¸Þ¸ð¸® ÇÒ´ç ÇÔ¼ö·Î °¡Àå ÃÖÇÏÀ§¿¡ ÀÖ´Â ÇÔ¼ö¶ó°í ÇÒ¼ö ÀÖ½À´Ï´Ù.
    • kmalloc, kmem_cache_alloc : SlabÇÒ´ç ¾Ë°í¸®Áò¿¡ ÀÇÇÏ¿© ±¸ÇöµÈ ÇÒ´çÀÚÀÔ´Ï´Ù.
  • Uncontiguous allocation
    • vm_alloc : ¹°¸®ÀûÀ¸·Î ¿¬¼ÓÀûÀÌÁö ¾ÊÀº ¸Þ¸ð¸® °ø°£À» ÇÒ´çÇÕ´Ï´Ù.

1.7. LinuxÀÇ ºÎÆÃÀýÂ÷

  1. Board power ON
  2. BIOS¿¡ ÀÇÇؼ­ Á¤ÇØÁø Post ÀýÂ÷¸¦ ¼öÇàÇÏ°í Bootsector¸¦ Àо Á¦¾î±ÇÀ» ³Ñ±è
  3. Bootsector·ÎºÎÅÍ Bootloader·Î Á¦¾î±ÇÀ» ³Ñ±è
  4. Bootloader ·ÎºÎÅÍ Kernel image¸¦ ÀоîµéÀÓ. (bsetup ºÎºÐÀ¸·Î Á¦¾î±Ç ³Ñ±è)
  5. bsetup ºÎºÐ¿¡¼­ ÇÊ¿äÇÑ ¸Þ¸ð¸®¼³Á¤À̳ª ±â¹Ý»çÇ× ÃʱâÈ­ÈÄ head+misc·Î Á¦¾î±Ç ³Ñ±è
  6. head+misc¿¡¼­ ½ÇÁ¦ ¾ÐÃàµÈ Ä¿³Î À̹ÌÁö¸¦ ¸Þ¸ð¸®·Î ¾ÐÃàÇØÁ¦ÇÏ°í ¾ÐÃàÇØÁ¦µÈ Ä¿³Î·Î Á¦¾î±Ç ³Ñ±è.
  7. Á¦¾î±ÇÀ» ³Ñ°Ü¹ÞÀº Ä¿³ÎÀº Bootloader·ÎºÎÅÍ ³Ñ°Ü¹ÞÀº ÀÎÀÚ°¡ ÀÖ´Â °æ¿ì À̸¦ È®ÀÎ (½Ã½ºÅÛ¸¶´Ù ´Ù¸¦¼ö ÀÖÀ½)
  8. Ä¿³ÎÀÎÀÚ root= ¿¡ ÇØ´çÇÏ´Â ÀÎÀÚ°¡ ÁÖ¾îÁö°Å³ª ±âº»°ªÀÌ ÀÖ´Â °æ¿ì ÇØ´ç root fsÀ» mount ÇÏ°í init= ¿¡ ÇØ´çÇÏ´Â ÀÎÀÚ°¡ ÁÖ¾îÁö°Å³ª ±âº»°ªÀÌ ÀÖ´Â °æ¿ì À̸¦ ½ÇÇà
  9. init= ÀÎÀÚ¿¡ ÀÇÇؼ­ ÁÖ¾îÁø init process´Â /etc/inittabÀ» È®ÀÎÇÏ°í sysinit Ç׸ñ¿¡ ÁÖ¾îÁø ½ÇÇàÆÄÀÏÀ» ½ÇÇàÇÕ´Ï´Ù.
    • ÀϺΠEmbedded system¿¡¼­´Â init process¸¦ ÁøÇàÇÏÁö ¾Ê°í linuxrc process¸¦ ½ÇÇàÇϵµ·Ï ÇÏ´Â °æ¿ìµµ ÀÖ½À´Ï´Ù.
    • init processÀÌÈÄÀÇ ÀýÂ÷´Â ¹èÆ÷ÆǸ¶´Ù ´Ù¼Ò Â÷ÀÌ°¡ ÀÖÀ¸¸ç ÀüÇô ´Ù¸¥ ¼öÇàÀýÂ÷¸¦ ³ÖÀ»¼öµµ ÀÖ´Â ºÎºÐÀÔ´Ï´Ù.
    • init process´Â Ç×»ó ProcessID°¡ 1ÀÎ ÇÁ·Î±×·¥À¸·Î ¸ðµç ApplicationÀÇ ÃÖ»óÀ§ Process·Î Á¸ÀçÇϸç ÇÏÀ§ processµéÀ» °ü¸®ÇÏ´Â ¿ªÇÒÀ» ¼öÇàÇÕ´Ï´Ù.
  10. sysinitÀÇ ½ÇÇàÀÌ ³¡³ª¸é respawn Ç׸ñÀ¸·Î ÁöÁ¤ÇÑ Å͹̳ÎÀåÄ¡¸¦ »ý¼ºÇÏ¸ç º¸ÅëÀº getty °¡ À̸¦ ó¸®ÇÏ°Ô µË´Ï´Ù.
  11. getty´Â login ÇÁ·Î±×·¥À» ½ÇÇàÇÏ¿© »ç¿ëÀڷκÎÅÍ login À» ¿ä±¸¹Þ´Â ÇÁ·ÒÇÁÆ®¸¦ »ý¼ºÇÕ´Ï´Ù.
  12. loginÀº login¿¡ ÇÕ´çÇÑ Á¶°ÇÀÌ ¸¸Á·ÇÏ°Ô µÇ¸é /bin/sh¸¦ ½ÇÇàÇÏ¿© shell»ç¿ë±ÇÇÑÀ» »ç¿ëÀÚ¿¡°Ô ÁÝ´Ï´Ù.

1.8. Shared Library¹öÁ¯¿¡ µû¸¥ ȣȯ

Linux¿¡¼­´Â Shared Library°¡ º¸Åë ÆÄÀϸíÀÌ lib<name>-<version>.so<> °ú °°Àº½ÄÀ¸·Î ÁÖ¾îÁý´Ï´Ù. ±×¸®°í Libary¸¦ ¸¸µé¶§ ÁÖ¾îÁö´Â soname¿¡ ÀÇÇؼ­ ÀÌ libraryÀÇ È£È¯À¯¹«°¡ °áÁ¤µÇ¾îÁý´Ï´Ù.

¾î¶² ½ÇÇàÇÁ·Î±×·¥ A°¡ ¾î¶² shared library¸¦ linkÇÏ¿´À»¶§ A´Â ½ÇÇàÇÒ¶§´Â ÇØ´ç shared libraryÀÇ sonameÀ¸·Î ÁÖ¾îÁø ÆÄÀϸíÀ» ã°Ô µË´Ï´Ù. ±×·¡¼­ °ú°Å¿¡ ¸¸µé¾ú´ø shared library¿Í ±¸Á¶°¡ ¸¹ÀÌ Æ²¾îÁ®¼­ »õ·Î¿î shared library°¡ ºôµåµÇ¾îµµ ¼­·Î ´Ù¸¥ sonameÀ» ºÎ¿©ÇÏ¿© ºôµåÇÏ¿© ÀÌ library¸¦ »ç¿ëÇÏ´Â ÇÁ·Î±×·¥µéÀÌ °øÁ¸ÇÒ¼ö ÀÖ°Ô ÇÕ´Ï´Ù.

¸¸¾à ³»°¡ ºôµåÇÑ ÇÁ·Î±×·¥ÀÌ ¾î¶² library¸¦ »ç¿ëÇÏ°í ¾î¶² sonameÀ» ÀÌ¿ëÇÏ´ÂÁö ¾Ë°í ½ÍÀ¸¸é "ldd"¶ó´Â ¸í·É¾î·Î À̸¦ È®ÀÎÇÒ¼ö ÀÖ½À´Ï´Ù.

1.9. Linux ÀÇ directory±¸Á¶

  • / : ÃÖ»óÀ§ directory·Î ¹Ýµå½Ã Á¸ÀçÇØ¾ß ÇÏ´Â ±âÁØÀ§Ä¡
  • /dev : System¿¡¼­ »ç¿ëÇÏ´Â ÀåÄ¡µé¿¡ ´ëÀÀÇϴ Ư¼öÀåÄ¡ÆÄÀϵéÀÌ Àִ°÷ÀÌ¸ç ºÎÆýà ¹Ýµå½Ã ÇÊ¿ä.
  • /etc : ¼³Á¤ÆÄÀϵéÀÌ ÀúÀåµÇ¾î ÀÖ´Â directory
  • /bin : ±âº»ÀûÀÎ ÇÁ·Î±×·¥µéÀÇ ½ÇÇàÆÄÀÏÀÌ ÀÖ´Â directory
  • /sbin : ¿î¿µ»óÀÇ ¸ñÀû¿¡ ÇÊ¿äÇÑ ½ÇÇàÆÄÀϵéÀÌ ÀÖ´Â directory
  • /lib : ±âº»ÀûÀ¸·Î »ç¿ëµÇ´Â libraryµéÀÌ ÀúÀåµÇ¾î ÀÖ´Â directory, (ld-linux, libc, libdl, libtermcap, libpthread µîÀÌ À§Ä¡)
  • /proc : systemÀÇ Á¤º¸¸¦ Á¦°øÇϰųª Á¦¾î¸¦ Á¦°øÇÏ´Â °¡»óÆÄÀÏÀÌ ÀÖ´Â directory
  • /var : systemÀÌ µ¿ÀÛÇϸ鼭 ºó¹øÈ÷ ¼öÁ¤ÀÌ µÇ°Å³ª »ý¼ºµÇ´Â ÆÄÀϵéÀÌ ÀúÀåµÇ´Â directory
  • /usr : »ç¿ëÀÚµéÀÇ ÇÁ·Î±×·¥°ú ¶óÀ̺귯¸® ¹× ±âŸ ºÎ¼öÀûÀÎ ÆÄÀϵéÀÌ ÀúÀåµÇ¾î ÀÖ´Â directory
  • /mnt : mount ¸¦ Çϱâ À§ÇÑ directory (¿©±â¿¡¸¸ mountÇÒ¼ö Àִ°ÍÀº ¾Æ´Ô)
  • /home : ÀÏ¹Ý »ç¿ëÀÚ °èÁ¤ÀÇ home directoryµéÀÌ ¸¸µé¾îÁö´Â °÷
  • /boot : Bootloader ¿¡ ÀÇÇؼ­ ºÎÆÃÇÏ°ÔµÉ Kernel imageµéÀÌ ÀúÀåµÇ´Â directory
  • /root : root °èÁ¤ÀÇ home directory

1.10. Real Time Linux (RT-Linux)¸¦ À§ÇÑ Scheduler°ü·Ã Á¶ÀÛ


Linux´Â ±âº»ÀûÀ¸·Î Hard RTOS´Â ¾Æ´Ï¸ç Soft RTOS¸¦ Áö¿øÇÏ´Â ±â´ÉÀ» °¡Áö°í ÀÖ½À´Ï´Ù.

¾Æ·¡ÀÇ ÇÔ¼öµéÀº CAP_SYS_NICEƯ±ÇÀ» °¡Áø User Application¿¡¼­ È£ÃâÇÒ¼ö ÀÖ´Â RealTime OSÀÇ µ¿ÀÛÀ» À§ÇÑ SchedulerÁ¦¾îÇÔ¼öµéÀÔ´Ï´Ù.
int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);
int sched_getscheduler(pid_t pid);
  • ÁÖ¾îÁø pidÀÇ process¿¡ ´ëÇÑ ScheduleÁ¤Ã¥À» ¼³Á¤ÇÒ¼ö ÀÖ½À´Ï´Ù.
  • policy´Â SCHED_OTHER, SCHED_BATCH, SCHED_IDLE, SCHED_FIFO, SCHED_RRÀÌ »ç¿ëµÉ¼ö ÀÖ½À´Ï´Ù.
    • SCHED_OTHER: ÀÏ¹Ý processµéÀÌ ÀÌ¿¡ ¼ÓÇϸç TimeSlice(quantum)¸¦ ÇÒ´ç¹Þ°í ³²Àº TimeSlice¸¦ ±âº»¿ì¼±¼øÀ§·Î ÃëÇÏ´Â ¹æ½ÄÀ¸·Î µ¿ÀÛÇÕ´Ï´Ù. (µ¿Àû¿ì¼±¼øÀ§ = ³²Àº TimeSlice + (20 - nice))
    • SCHED_FIFO: SCHED_OTHERº¸´Ù ³ôÀº ¿ì¼±¼øÀ§¸¦ °¡Áö¸ç TimeSliceÀÇ °³³äÀÌ ¾ø´Â ¹æ½ÄÀ¸·Î µ¿ÀÛÇÕ´Ï´Ù. Áï, ½º½º·Î CPU¸¦ ¹ÝȯÇÏÁö ¾Ê´Âµ¿¾ÈÀº CPU¸¦ ¼±Á¡ÇÕ´Ï´Ù.
    • SCHED_RR: SCHED_OTHERº¸´Ù ³ôÀº ¿ì¼±¼øÀ§¸¦ °¡Áö¸ç TimeSlice°¡ Á¸ÀçÇÏ°í °°Àº ¿ì¼±¼øÀ§ÀÇ process´Â Round-Robin ¹æ½ÄÀ¸·Î Scheduleµ¿ÀÛÀ» ÇÕ´Ï´Ù.
    • SCHED_BATCH: Idle schedule policy °³³äÀ¸·Î ½ÇÇàµÇ´Â process°¡ ¾øÀ»¶§ µ¿ÀÛÇÏ´Â ¹æ½ÄÀ¸·Î Real-Time°ú ¹Ý´ë¶ó°í º¸½Ã¸é µË´Ï´Ù.
int sched_get_priority_max(int policy);
int sched_get_priority_min(int policy);
  • ÁÖ¾îÁø Á¤Ã¥ÀÇ ¿ì¼±¼øÀ§ÀÇ ¹üÀ§¸¦ È®ÀÎÇϱâ À§Çؼ­ »ç¿ëÇÕ´Ï´Ù.
int sched_setparam(pid_t pid, const struct sched_param *param);
int sched_getparam(pid_t pid, struct sched_param *param);
  • ÁÖ¾îÁø pidÀÇ process¿¡ ´ëÇÑ ScheduleÁ¤º¸¼³Á¤ ¹× È®ÀÎÀ» À§ÇØ »ç¿ëÇÕ´Ï´Ù.
int sched_yield(void);
  • ÀÌ ÇÔ¼ö¸¦ È£ÃâÇÑ processÀÇ scheduleÀ» ´ÙÀ½¼øÀ§·Î ¾çµµÇÕ´Ï´Ù.
int sched_setaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
  • ƯÁ¤ CPU¸¦ »ç¿ëÇϰųª »ç¿ëÇÏÁö ¾Êµµ·Ï ÇÕ´Ï´Ù.
  • CPU_ZERO, CPU_SET, CPU_CLR macro¿Í ÇÔ²² »ç¿ëÇÕ´Ï´Ù.
int nice(int inc);
  • ScheduleÁ¤Ã¥ÀÌ SCHED_OTHERÀÎ ÇÁ·Î¼¼½º¿¡¼­´Â nice°ªÀ» Á¶Á¤ÇÏ¿© TimeSlice¿Í ¿ì¼±¼øÀ§¿¡ ¿µÇâÀ» ÁÝ´Ï´Ù.
  • ScheduleÁ¤Ã¥ÀÌ SCHED_RRÀÎ ÇÁ·Î¼¼½º¿¡¼­´Â TimeSlice¿¡¸¸ ¿µÇâÀ» ÁÝ´Ï´Ù.

1.11. Process °ü¸®

ÀüÅëÀûÀÎ Unix system¿¡¼­´Â Process¸¦ »ý¼ºÇÒ¶§ ºÎ¸ðProcess·ÎºÎÅÍ ÀÚ¿øÀ» º¹Á¦ÇÏ¿© »õ·Î¿î Process¸¦ »ý¼ºÇÕ´Ï´Ù. ±×·¯³ª ÀÌ·¸°Ô ÀÚ¿øÀ» ¸ðµÎ º¹Á¦ÇÏ´Â °æ¿ì ÀÚ½ÄProcess°¡ ¸ðµç ÀÚ¿øÀ» µ¿ÀÏÇÏ°Ô ¸ðµÎ È°¿ëÇϴ°ÍÀÌ ¾Æ´Ï°í ±× ÀϺκи¸À» »ç¿ëÇÏ°Ô µÇ¹Ç·Î ºñÈ¿À²ÀûÀÎ ÀÚ¿ø¼Ò¸ð°¡ ÀÖ´Ù°¡ ÆÇ´ÜÇÏ¿© Linux¿¡¼­´Â ´ÙÀ½°ú °°Àº ÇØ°á¹æ¾ÈÀ» »ç¿ëÇÕ´Ï´Ù.
  • Copy on write ¹æ½Ä Àû¿ë : ÀÚ½ÄProcess »ý¼º½Ã ¸ðµç ÀÚ¿øÀº ºÎ¸ðProcess·ÎºÎÅÍ º¹Á¦µÇÁö ¾ÊÀº »óÅ¿¡¼­ ½ÃÀÛÇϸç ÀÚ½ÄProcess°¡ ½ÇÁ¦ ¹°¸®Àû page¿¡ Á¢±ÙÀ» ÇÒ¶§ ÀÚ¿øÀÌ º¹Á¦µÇ´Â ¹æ¹ý
  • Light weight process : ºÎ¸ðProcess¿Í ÀÚ½ÄProcessÀÇ ÁÖ¼Ò°ø°£À» °øÀ¯ÇÏ°í ½ÇÇ๮¸Æ¿¡ ÇÊ¿äÇÑ Á¤º¸¸¸ º°µµ·Î ¿î¿µÇÏ´Â ¹æ½Ä
  • vfork : ºÎÈ£Process¿Í ÀÚ½ÄProcessÀÇ ¸Þ¸ð¸® ÁÖ¼Ò °ø°£À» °øÀ¯
uid_t getuid(void);
uid_t geteuid(void);
int setuid(uid_t uid);
int seteuid(uid_t euid);
gid_t getgid(void);
gid_t getegid(void);
int setgid(gid_t gid);
int setegid(gid_t egid);

pid_t fork(void);
pid_t vfork(void);

int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);

void exit(int status);

pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);

int system(const char *command);

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
int pthread_join(pthread_t thread, void **retval);
int pthread_detach(pthread_t thread);


pid_t pid = vfork();
if(pid == ((pid_t)(-1))) perror("fork");
else if(pid == ((pid_t)0)) { /* ÀÚ½Ä process */
    char * const arg[] = { "/bin/ls", "-al", (char *)0 };
    (void)execvp(arg[0], arg);
    exit(0);
}
else (void)waitpid(pid, (int *)0, 0); /* ºÎ¸ð process */


1.12. Signal

  • SignalÀº processµé¿¡°Ô Ưº°ÇÑ Event¿¡ ´ëÇؼ­ ¹ÝÀÀÇϰųª Á¶Ä¡ÇÒ¼ö ÀÖµµ·Ï Çϱâ À§Çؼ­ »ç¿ëµË´Ï´Ù.
  • SignalÀº »ó´ë process°¡ ¾î¶² ¼öÇà»óÅ¿¡ ÀÖ´ÂÁö »ó°ü¾øÀÌ ¹ß»ý½Ãų¼ö ÀÖ½À´Ï´Ù.
  • ¼öÇàÁßÀÌ ¾Æ´Ñ process¿¡°Ô signalÀ» º¸³»¸é ÇØ´ç process°¡ ±ú¾î³ª¸é¼­ SignalÀ» ó¸®ÇÏ°Ô µË´Ï´Ù.
  • SignalÀ» Àü¼ÛÇßÀ¸³ª ¾ÆÁ÷ 󸮵ÇÁö ¾ÊÀº SignalÀº Pending signalÀ̶ó°í Çϸç Pending signalÀ» ¹Ýº¹Çؼ­ º¸³»´Â °æ¿ì´Â ¹«½ÃµË´Ï´Ù.
  • SIGKILL°ú SIGSTOP signalÀº ¿¹¿ÜÀûÀ¸·Î block½Ãų¼ö ¾ø½À´Ï´Ù.

    SIGHUP    SIGINT     SIGQUIT   SIGILL    SIGTRAP   SIGABRT    SIGIOT    SIGBUS
    SIGFPE    SIGKILL    SIGUSR1   SIGSEGV    SIGUSR2   SIGPIPE    SIGALRM   SIGTERM
    SIGSTKFLT SIGCHLD    SIGCONT   SIGSTOP    SIGTSTP   SIGTTIN    SIGTTOU   SIGURG
    SIGXCPU   SIGXFSZ    SIGVTALRM SIGPROF    SIGWINCH  SIGIO      SIGPOLL   SIGPWR
    SIGSYS
    


    typedef void (*sighandler_t)(int);
    
    sighandler_t signal(int signum, sighandler_t handler);
    int kill(pid_t pid, int sig);
    int raise(int sig);
    int pause(void);
    
    unsigned int alarm(unsigned int seconds); /* SIGALRM */
    


1.13. File descriptorÀÇ Á¢±Ù

¸®´ª½º´Â ´Ù¾çÇÑ ÀåÄ¡µéÀ» Ưº°ÇÑ ÆÄÀÏó·³ Ãë±ÞÇÕ´Ï´Ù.
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_t mode);
int close(int fd);
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
off_t lseek(int fd, off_t offset, int whence);
int fcntl(int fd, int cmd, ... /* arg */ );
int ioctl(int d, int request, ...);
int remove(const char *pathname);
DIR *opendir(const char *name);
int readdir(unsigned int fd, struct old_linux_dirent *dirp, unsigned int count);
int closedir(DIR *dirp);
int dup(int oldfd);
int dup2(int oldfd, int newfd);
int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);
int link(const char *oldpath, const char *newpath);
int unlink(const char *pathname);
int symlink(const char *oldpath, const char *newpath);
ssize_t readlink(const char *path, char *buf, size_t bufsiz);
int utime(const char *filename, const struct utimbuf *times);
int mkdir(const char *pathname, mode_t mode);
int rmdir(const char *pathname);


1.14. Inter Process Communication (IPC)

  • IPC´Â DataÀÇ Àü¼Û°ú °øÀ¯, EventÀü¼Û, ÀÚ¿øÀÇ °øÀ¯, ProcessÁ¦¾îµîÀ» ¸ñÀûÀ¸·Î ¸¸µé¾îÁø Ưº°ÇÑ Process°£ Åë½Å¼ö´ÜÀÔ´Ï´Ù.
  • ´ÙÀ½°ú °°Àº IPCÀÀ¿ëÀÚ¿øÀÌ ¸®´ª½º¿¡¼­ Á¦°øµË´Ï´Ù.
    • pipe (¹ÝÀÌÁß Åë½Å)
    • FIFO (named pipe)
    • stream pipe (ÀüÀÌÁß Åë½Å)
    • named stream pipes
    • Message queue
    • Semaphore
    • Socket
    • Stream

  • /* pipe */
    int pipe(int pipefd[2]);
    
    /* stream pipe */
    FILE *popen(const char *command, const char *type);
    int pclose(FILE *stream);
    
    /* fifo */
    int mkfifo(const char *pathname, mode_t mode);
    int mknod(const char *pathname, mode_t mode, dev_t dev);
    
    /* ¼¼¸¶Æ÷¾î */
    int semget(key_t key, int nsems, int semflg);
    int semctl(int semid, int semnum, int cmd, ...);
    int semop(int semid, struct sembuf *sops, unsigned nsops);
    
    /* ¸Þ½ÃÁöÅ¥ */
    int msgget(key_t key, int msgflg);
    int msgctl(int msqid, int cmd, struct msqid_ds *buf);
    int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
    ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
    
    /* °øÀ¯¸Þ¸ð¸® */
    int shmget(key_t key, size_t size, int shmflg);
    void *shmat(int shmid, const void *shmaddr, int shmflg);
    int shmdt(const void *shmaddr);
    int shmctl(int shmid, int cmd, struct shmid_ds *buf);
    


1.15. LinuxÀÇ ½Ã°£

  • ±âº»ÀûÀ¸·Î Timer interrrupt¿¡ ÀÇÁ¸ÇÏ´Â tick¼ö¸¦ Àü¿ªº¯¼ö jiffiesÀ¸·Î Interrupt tick¸¶´Ù "++jiffies"À» ¼öÇàÇÏ¿© TickÀ» count ÇÕ´Ï´Ù.
  • óÀ½ ºÎÆÃÀ» Çϸé jiffies°ªÀº 0ºÎÅÍ ½ÃÀÛÇϸç ÀÌ°ÍÀ» °¡Áö°í Ãʱâ RTC·ÎºÎÅÍ Àоî¿Í ±× ½Ã°£À» ÇϽðí System timeÀ» °ü¸®ÇÏ°Ô µÇ¸ç jiffies¸¦ ´Ü¼øÈ÷ msec´ÜÀ§·Î ȯ»êÇÏ¸é ºÎÆÃÈÄÀÇ ½Ã°£ÀÎ uptimeÀ» À¯ÃßÇÒ¼ö ÀÖ°Ô µË´Ï´Ù.
  • Linux¿¡¼­ Timer interruptÀÇ ÁÖ±â´Â ±âº»ÀûÀ¸·Î ´ëºÎºÐÀÇ ½Ã½ºÅÛÀº 100Hz ·Î µ¿ÀÛÇϵµ·Ï ¼³°èµË´Ï´Ù. ÇÏÁö¸¸ 100HzÁÖ±â·Î µ¿ÀÛÇÏ°Ô µÇ¸é jiffies°ªÀº 10msec¸¶´Ù Çѹø¾¿ Tick count¸¦ ÇÏ°Ô µÇ¹Ç·Î 1msec´ÜÀ§ÀÇ ¼¼ºÎ ½Ã°£°ü¸®¸¦ ÇÒ¼ö ¾ø°Ô µË´Ï´Ù. À̸¦ È®ÀåÇϱâ À§Çؼ­ Kernel (menu)config ¿¡ º¸¸é HZ »ó¼ö¸¦ º¯°æÇÒ¼ö ÀÖµµ·Ï µÇ¾î ÀÖÀ¸¸ç ÀÌ°ÍÀ» 1000Hz·Î º¯°æÇϸé msec´ÜÀ§ÀÇ ½Ã°£°ü¸®°¡ °¡´ÉÇØÁý´Ï´Ù.
  • ÀÏ¹Ý PC¿¡¼­´Â i686 ÀÌÇÏ ½Ã½ºÅÛÀÇ °æ¿ì 8254 timer¸¦ ÀÌ¿ëÇϱ⠶§¹®¿¡ 10msecÀÌÇÏ·Î Timer tick À» »ç¿ëÇÒ¼ö ¾ø½À´Ï´Ù. ÀÌ´Â °ð ÀÏ¹Ý PC¿¡¼­´Â 10msecÀÌÇÏ´Â »ç¿ëÇÏÁö ¾Ê½À´Ï´Ù. ±×·¯³ª i686±âÁ¸ ÀÌ»óºÎÅÍ´Â HPET timer¸¦ ÀÌ¿ëÇÏ¿© º¸´Ù Á¤¹ÐÇÏ°Ô »ç¿ë°¡´ÉÇÕ´Ï´Ù.
  • ¿äÁò¿¡¼­´Â CPU¿¡ °ø±ÞµÇ´Â clock¿¡ ´ëÇÑ tick count¸¦ register·Î Àо¼ö ÀÖ´Â °æ¿ì°¡ ¸¹½À´Ï´Ù. ÇÏÁö¸¸ ±âº»ÀûÀ¸·Î Linux¿¡¼­´Â ±×·¯ÇÑ ÀÚ¿øÀ» Á÷Á¢ÀûÀ¸·Î Á¦°øÇÏÁö ¾Ê½À´Ï´Ù. ¸¸¾à CPU clock ÀÚ¿øÀ» ÀÌ¿ëÇÏ·Á¸é Assembly level¿¡¼­ Á÷Á¢ ÇØ´ç register¸¦ Àо »ç¿ëÇØ¾ß ÇÕ´Ï´Ù. (ÀÌ°ÍÀº OpÀÚüµµ ClockÀ» ¼Ò¸ðÇϱ⠶§¹®¿¡ Ä¿³Î¿¡¼­ User mode·Î ÇØ´ç ÀÚ¿øÀ» Áö¿øÇÑ´Ù´Â°Ô Àǹ̰¡ Å©Áö ¾Ê´Ù°í ÆÇ´ÜÇÏ´Â°Í °°½À´Ï´Ù.)

1.15.1. uptime

  • uptimeÀº ½Ã½ºÅÛÀÌ ºÎÆÃÇÑ ÀÌÈĺÎÅÍ ¾ó¸¶³ª °æ°úµÇ¾ú´ÂÁö¸¦ ¸»ÇÏ´Â ½Ã°£±âÁØÀÔ´Ï´Ù.
  • °£´ÜÈ÷ À̸¦ È®ÀÎÇÏ·Á¸é Shell¿¡¼­ "cat /proc/uptime"¸í·ÉÀ¸·Î È®Àΰ¡´ÉÇÕ´Ï´Ù.
  • User mode¿¡¼­ C¾ð¾î·Î uptimeÀ» ¾ò¾î¿À·Á¸é "sysinfo"¶ó´Â ÇÔ¼ö¸¦ ÀÌ¿ëÇÒ¼ö ÀÖ½À´Ï´Ù.
    #include <sys/sysinfo.h>
    #include <stdio.h>
    #include <stdlib.h>

    int main(int s_argc, char **s_argv)
    {
        struct sysinfo s_sysinfo_local;

        (void)s_argc;
        (void)s_argv;

        if(sysinfo((struct sysinfo *)(&s_sysinfo_local)) == 0) {
            (void)fprintf(stdout, "uptime is %ld sec\n",
    (long)s_sysinfo_local.uptime);
        }

        return(EXIT_SUCCESS);
    }
  • uptimeÀº ½Ã½ºÅÛÀÌ ºÎÆõÈÈĺÎÅÍÀÇ ½Ã°£À» ¸»ÇϹǷΠ¾î¶² ¹æ¹ýÀ¸·Îµç ½Ã½ºÅÛÀÌ ÄÑÁ®ÀÖ´Â µ¿¾È¿¡´Â ½Ã°£ÀÇ ¿ªÀ¸·Î È帣Áö ¾ÊÀ¸¸ç ÀÓÀÇ·Î º¯°æÇÒ¼ö ¾ø´Â ÀÚ¿øÀÔ´Ï´Ù.

1.15.2. System time˼?

  • ÀϹÝÀûÀ¸·Î Shell ¿¡¼­ "date"¸í·ÉÀ¸·Î È®Àΰ¡´ÉÇÑ ½Ã°£À» ¸»ÇÕ´Ï´Ù. Áï, ÀϹÝÀûÀÎ ¿ì¸®°¡ ¾Ë°í ÀÖ´Â ½Ã°èÀÚ¿øÀÔ´Ï´Ù.
  • ¸®´ª½º¿¡¼­´Â ÀÌ°ÍÀ» UTC·Î ¼³Á¤ÇÏ°í localtime zoneÁ¤º¸¿¡ ÀÇÇؼ­ º¯È¯ÇÏ¿© »ç¿ëÇÏ´Â ¹æ¹ýÀ» ¸¹ÀÌ »ç¿ëÇϸç Windowsó·³ ¾Æ¿¹ UTC´Â °í·ÁÇÏÁö ¾Ê°í (Time offsetÀ» »ç¿ëÇÏÁö ¾Ê´Â) Á÷Á¢ Localtime zoneÀ¸·Î °ü¸®ÇÏ´Â ¹æ¹ý·Î »ç¿ë°¡´ÉÇÕ´Ï´Ù. ÀÌ·¯ÇÑ Á¤º¸´Â "/etc/localtime" ÆÄÀÏ°ú "/etc/adjtime"ÆÄÀÏÀÌ °ü¿©ÇÏ°Ô µË´Ï´Ù.
  • System timeÀº C¾ð¾îÀÇ "time_t" typeÀ¸·Î ÀúÀåµÇ¸ç °ú°Å¿¡´Â 32bit Å©±â¸¦ °¡Á³À¸³ª ¿äÁò¿¡´Â 64bitÅ©±â¸¦ ¼±È£ÇÕ´Ï´Ù.
  • User mode¿¡¼­ C¾ð¾î·Î System timeÀ» ¾ò¾î¿À·Á¸é "time"À̶ó´Â ÇÔ¼ö¸¦ ÀÌ¿ëÇÒ¼ö ÀÖ½À´Ï´Ù. ±×¸®°í ÀÌ°ÍÀ» »ç¶÷ÀÌ ¾Ë¾Æ¸ÔÀ»¼ö ÀÖ´Â Local timeÀ¸·Î ¾ò¾î¿À·Á¸é "localtime"ÇÔ¼ö¸¦ ÀÌ¿ëÇÒ¼ö ÀÖÀ¸¸ç UTC timeÀ¸·Î ¾ò¾î¿À·Á¸é "gmtime"À̶ó´Â ÇÔ¼ö¸¦ ÀÌ¿ëÇÒ¼ö ÀÖ½À´Ï´Ù.
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>

    int main(int s_argc, char **s_argv)
    {
        time_t s_time_local;

        if(time((time_t *)(&s_time_local)) != ((time_t)(-1))) {
            struct tm s_tm_local;

            (void)memcpy((void *)(&s_tm_local), localtime((time_t
    *)(&s_time_local)), sizeof(struct tm));
            (void)fprintf(stdout, "Áö¿ª½Ã°£: %d/%d/%d %02d:%02d:%02d\n",
    s_tm_local.tm_year + 19000, s_tm_local.tm_mon + 1, s_tm_local.tm_mday,
    s_tm_local.tm_hour, s_tm_local.tm_min, s_tm_local.tm_sec);

            (void)memcpy((void *)(&s_tm_local), gmtime((time_t
    *)(&s_time_local)), sizeof(struct tm));
            (void)fprintf(stdout, "±×¸®´ÏÄ¡ Ç¥ÁؽÃ: %d/%d/%d %02d:%02d:%
    02d\n", s_tm_local.tm_year + 19000, s_tm_local.tm_mon + 1,
    s_tm_local.tm_mday, s_tm_local.tm_hour, s_tm_local.tm_min,
    s_tm_local.tm_sec);

        }

        return(EXIT_SUCCESS);
    }
  • ¹Ý´ë·Î ½Ã½ºÅÛ ½Ã°£À» ³»°¡ ¿øÇÏ´Â ½Ã°£À¸·Î ¼³Á¤ÇÏ·Á¸é ´ÙÀ½°ú °°ÀÌ ÇÒ¼ö ÀÖ½À´Ï´Ù.
    #include <time.h>

    ...

    struct tm s_set_tm_local;
    time_t s_set_time_local;

    (void)memset((void *)(&s_set_tm_local), 0, sizeof(s_set_tm_local));
    s_set_tm_local.tm_year = <³âµµ> - 1900;
    s_set_tm_local.tm_mon = <¿ù> - 1;
    s_set_tm_local.tm_mday = <ÀÏ>;
    s_set_tm_local.tm_hour = <½Ã>;
    s_set_tm_local.tm_min = <ºÐ>;
    s_set_tm_local.tm_sec = <ÃÊ>;
    s_set_time_local = mktime((struct tm *)(&s_set_tm_local)); /* struct
    tm±¸Á¶Ã¼Çü½ÄÀ» time_t Çü½ÄÀ¸·Î º¯È¯ */

    if(stime((time_t *)(&s_set_time_local)) == 0) {
        /* ¼³Á¤¿Ï·á */
    }

    ...
  • System timeÀº Àü¿øÀÌ ²¨Áö¸é ÃʱâÈ­°¡ µË´Ï´Ù. Áï, RTCÀÚ¿ø°ú´Â ´Ù¸¥ ÀÚ¿øÀÔ´Ï´Ù. ¸¸¾à Àü¿øÀÌ ²¨Á³´Ù°¡ ÄÑÁ®µµ ½Ã°£ÀÌ °è¼Ó À¯ÁöÇϵµ·Ï ÇÏ·Á¸é RTCÀÚ¿øÀ¸·ÎºÎÅÍ ºÎÆýÿ¡ System timeÀ» ¼³Á¤ÇÏ´Â ´Ü°è°¡ ÇÊ¿äÇÕ´Ï´Ù. (ÀÏ¹Ý ¸®´ª½º¿¡¼­´Â ÀÌ°ÍÀ» "/sbin/hwclock"¸í·É¾î°¡ ¼öÇàÇÏ°Ô µË´Ï´Ù.)
  • System timeÀ» "time", "stime"ÇÔ¼ö·Î ÀÌ¿ëÇϸé ÃÊ´ÜÀ§ÀÇ ½Ã°£À¸·Î¸¸ °ü¸®ÇÒ¼ö ÀÖ´Â ¹Ý¸é gettimeofday, settimeofday¸¦ ÀÌ¿ëÇϸé microsecond´ÜÀ§·Î °ü¸®ÇÒ¼ö ÀÖ½À´Ï´Ù. ÇÏÁö¸¸ ½ÇÁ¦·Î Microsecond´ÜÀ§±îÁö Á¤¹Ð¼ºÀ» º¸ÀåÇÏÁö ¸øÇϸç ÀÌ°ÍÀº Ä¿³ÎÀÇ HZ»ó¼ö°¡ Á¤ÀÇÇÏ´Â ±âÁØ¿¡ ÀÇÁ¸ÇÏ¿© Á¤¹Ð¼ºÀ» °®½À´Ï´Ù. Áï, HZ»ó¼ö°¡ 100Àΰæ¿ì 10msec´ÜÀ§ÀÇ Á¤¹Ðµµ¸¦ °®°Ô µË´Ï´Ù.

1.15.3. System clock tick ÀÚ¿ø

  • ÀÌ°ÍÀº uptime°ú Èí»çÇÏ°í °ÅÀÇ µ¿ÀÏÇÑ ÀÚ¿øÀ¸·Î ±¸ÇöµÇ¾ú´Ù°í º¸Áö¸¸ ½Ã½ºÅÛ¸¶´Ù Á»´õ ³ôÀº Á¤¹Ðµµ¸¦ À§ÇÏ¿© ±¸ÇöµÇ±âµµ Çϱ⠶§¹®¿¡ WindowsÀÇ Multimedia timer ÀÚ¿ø°ú Èí»çÇÏ´Ù°í º¸½Ã¸é µË´Ï´Ù. °á±¹ ÀÌÀÚ¿ø ¿ª½Ã jiffies·ÎºÎÅÍ ½Ã°£ÀÚ¿øÀ» ÀÌ¿ëÇÏ´Â ¹æ½ÄÀ» ÀÌ¿äÇÏ´Â ½Ã½ºÅÛµéÀÌ ¸¹±â ¶§¹®¿¡ jiffiesÀÇ tick ÁÖ±â(HZ»ó¼ö)¿¡ ÀÇÁ¸ÇÕ´Ï´Ù. ÇÏÁö¸¸ ÀϺΠEmbedded CPU vendorµé¿¡¼­´Â ÀÌ°ÍÀÌ Àü¿ë °í±Þ Timer ÀÚ¿øÀ¸·ÎºÎÅÍ ±¸ÇöµÇ´Â °æ¿ì°¡ À־ º¸ÅëÀº ÀÌ ÀÚ¿øÀ» ¸¹ÀÌµé »ç¿ëÇÕ´Ï´Ù. ±×¸®°í ½Ã°£ÀÇ ¿ª·ùÇö»óÀÌ uptime°ú ¸¶Âù°¡Áö·Î Á¸ÀçÇÏÁö ¾Ê±â ¶§¹®¿¡µµ ¸¹ÀÌ »ç¿ëÇÕ´Ï´Ù.
  • User mode¿¡¼­ C¾ð¾î·Î System clock tickÀ» ¾ò¾î¿À·Á¸é "times"¶ó´Â ÇÔ¼ö¸¦ ÀÌ¿ëÇÒ¼ö ÀÖÀ¸¸ç Clock tick ÁÖ±â´Â "sysconf(_SC_CLK_TCK)" ÇÔ¼ö·Î ¾ò¾î¿Ã¼ö ÀÖ½À´Ï´Ù. Clock tick ÁÖ±â´Â ´ëºÎºÐÀÇ ½Ã½ºÅÛµéÀº jiffiesÀÇÁ¸¹æ½Ä¿¡ ÀÇÇؼ­ HZ»ó¼ö°¡ µÇÁö¸¸ Embedded CPU vendorµéÁß ÀϺδ ÀÌ°ÍÀ» Á»´õ ³ôÀº Á¤¹Ð¼ºÀ¸·Î ±¸ÇöÇÕ´Ï´Ù. ¾Æ·¡ÀÇ ¿¹Á¦¼Ò½º´Â ÀÌ ÀÚ¿øÀ» ÀÌ¿ëÇÏ¿© msec ´ÜÀ§ÀÇ »ó´ë½Ã°£°ªÀ» ±¸ÇÒ¼ö ÀÖ´Â Time Stamp ÇÔ¼ö¸¦ ±¸ÇöÇÑ°ÍÀÔ´Ï´Ù.
  • ¾Æ·¡ÀÇ ¿¹Á¦¿¡¼­ times ÇÔ¼öÀÇ ¹Ýȯ°ªÀ» ÀÌ·¯ÇÑ ¿ëµµ·Î È°¿ëÇÒ¼ö ÀÖ´Â °æ¿ìµµ ÀÖ½À´Ï´Ù. ÇÏÁö¸¸ ÀÌ »çÇ×Àº Ä¿³ÎÀÇ ±¸Çö¹æ½ÄÀ» È®ÀÎÇÏ´Â°Ô ÇÊ¿äÇÏ¸ç °æ¿ì¿¡ µû¶ó¼­ ƯÁ¤ ½Ã°£ÀÌ Áö³ª¸é Overflow¿¡ ´ëÇÑ °í·Á°¡ ÀÖ¾î¾ß ÇÕ´Ï´Ù. (ÀÇ¿Ü·Î ÇÊÀÚÀÇ °æÇè»ó timesÀÇ ±¸ÇöÀº ¸Å¿ì È¥¶õ½º·¯¿î Overflow ´ëÀÀ°í·Á°¡ ÇÊ¿äÇÕ´Ï´Ù.)
    • ÀϺÎȯ°æ¿¡¼­´Â times ÇÔ¼öÀÇ ¹Ýȯ°ª clock() / HZ °¡ ºÎÆÃÁ÷ÈÄ 289ÃÊ Âë¿¡¼­ Overflow°¡ -1135, -1134, 1133, 1132, 1131, 1130, .., 1, 0, 1, 2, 3, 4, ... ¿Í °°Àº½ÄÀ¸·Î ¹ß»ýÇÕ´Ï´Ù. ±×¸® ÁÁÀº Overflow ¹æ½ÄÀº ¾Æ´Ñµí ½Í½À´Ï´Ù.
  • #include <sys/time.h>
    #include <time.h>
    #include <unistd.h>

    typedef unsigned long long __mz_time_stamp_t;
    #define mz_time_stamp_t __mz_time_stamp_t

    typedef struct mz_timer_ts {

        /* need shadow */
        long clock_tick;
        clock_t prev_clock;
        mz_time_stamp_t time_stamp;

    }__mz_timer_t;
    #define mz_timer_t __mz_timer_t

    static mz_time_stamp_t __mz_timer_time_stamp(mz_timer_t *s_timer)
    {
        clock_t s_clock;

    #if defined(__linux__)
        /* get linux kernel's jiffes (tick counter) */
        s_clock = times((struct tms *)0);
    #else
        do {
            struct tms s_tms;
            s_clock = times((struct tms *)(&s_tms));
        }while(0);
    #endif

        if(s_clock == ((clock_t)(-1))) {
            /* overflow clock timing */
            return(s_timer->time_stamp);
        }

        if(s_timer->clock_tick <= 0l) {
            /* get ticks per second */
            s_timer->clock_tick = sysconf(_SC_CLK_TCK);
            if(s_timer->clock_tick <= 0l) {
                /* invalid clock tick */
                return(s_timer->time_stamp);
            }

            s_timer->prev_clock = s_clock;
        }

        /* update time stamp (clock to upscale) */
        s_timer->time_stamp += (((mz_time_stamp_t)(s_clock -
    s_timer->prev_clock)) * ((mz_time_stamp_t)1000)) /
    ((mz_time_stamp_t)s_timer->clock_tick);
        s_timer->prev_clock = s_clock;

        return(s_timer->time_stamp);
    }

    static mz_time_stamp_t mz_get_time_stamp_msec(mz_timer_t *s_timer)
    {
        statuc mz_timer_t g_global_timer_local = {
            0l, (clock_t)0, (mz_time_stamp_t)1000u
        };

        return(__mz_timer_time_stamp((mz_timer_t
    *)(&g_global_timer_local));
    }


1.15.4. POSIX±Ô°ÝÀÇ clock_gettime ½Ã°£ÀÚ¿ø

  • Á»´õ È°¿ë°¡Ä¡°¡ ³ôÀº ½Ã°£ÀÚ¿øÀ¸·Î´Â POSIX±Ô°Ý¿¡¼­ ¸í½ÃÇÏ°í ÀÖ´Â clock_gettimeÇÔ¼ö°¡ ÀÖ½À´Ï´Ù. (ÀÀ¿ë¿¹: [http]Àý´ëÀû ¼ø¹æÇ⠽ð£ÀÚ¿ø ¾ò±â[])
  • "unistd.h" header¿¡¼­ "_POSIX_VERSION" °ú "_POSIX_TIMER" °¡ defineµÇ¾î Àִ ȯ°æÀ̶ó¸é clock_gettime ÇÔ¼ö´Â »ç¿ë°¡´ÉÇÒ°Ì´Ï´Ù.
  • POSIX°è¿­ ȯ°æ¿¡¼­´Â ¿©·¯°¡Áö ½Ã°£ÀÚ¿øÀ» clock_gettime À¸·Î ¸ðµÎ ´ëüÇϴ°ÍÀ» ±ÇÀ¯ÇÏ´Â Ãß¼¼ÀÔ´Ï´Ù.

1.15.5. ±× ¹Û¿¡ ½Ã°£ÀÚ¿ø

  • Intel CPUÀÇ °æ¿ì Real Time Stamp Clock À̶ó´Â ÀÚ¿øÀ» Á¦°øÇϴµ¥ ¸®´ª½º¿¡¼­ Á÷Á¢ÀûÀ¸·Î Á¦°øÇÏÁö ¾ÊÁö¸¸ ´ÙÀ½°ú °°ÀÌ Assmebly·Î ÀÐÀ»¼ö ÀÖ½À´Ï´Ù. »ç½Ç»ó °¡Àå ÀûÈ®ÇÑ ½Ã°£ÀÚ¿øÀÎ Real Time Stamp ClockÀº ´ëºÎºÐÀÇ ½Ã½ºÅÛ¿¡¼­ ¸®´ª½º¿¡ ±¸ÇöµÇÁö ¾Ê¾ÒÁö¸¸ ÀϺΠEmbedded systemÀÇ °æ¿ì System clock tick ÀÚ¿øÀ¸·Î ±¸ÇöµÇ´Â °æ¿ì°¡ ¸¹½À´Ï´Ù.
    unsigned long long int mz_get_cpu_clock(void)
    {
        unsigned long long int s_qword;

        __asm__ volatile(
            "rdtsc\n\t" : "=A"(s_qword)
        );

        return(s_qword);
    }
  • ¸®´ª½º´Â User mode¿¡¼­´Â Scheduler ¸¦ Á÷Á¢ÀûÀ¸·Î Á¦¾îÇÒ¼ö ¾ø±â ¶§¹®¿¡ Context¹ÝÀÀ¿¡ ÀÇÇؼ­ ´Ù¼Ò ½Ã°£ÀÇ ¿ÀÂ÷°¡ ¹ß»ýÇÒ¼ö ÀÖ½À´Ï´Ù. ´ë·« ÀÌ°ÍÀº HZ»ó¼ö¿Í DriverµéÀÇ ±¸Çö¹æ½Ä¿¡ ÀÇÇؼ­ ¿µÇâÀ» ¹ÞÀ¸¸ç º¸Åë 0~50msecÁ¤µµÀÇ ¿ÀÂ÷À²ÀÌ ¹ß»ýÇÒ¼ö ÀÖ½À´Ï´Ù. ÀÌ°ÍÀº Windowsµµ ±×·¸±â ¶§¹®¿¡ À߸øµÈ »çÇ×ÀÌ ¾Æ´Õ´Ï´Ù. ÇÏÁö¸¸ Multi media¸¦ ´Ù·ê¶§ Jitter time ¿¡ ´ëÇÑ ¹üÀ§°¡ RTOSº¸´Ù´Â Á¶±Ý ½Å°æÀ» ½á¾ß ÇѴٴ°ͻÓÀÌ Â÷ÀÌ´Â ¾ø½À´Ï´Ù.
  • ¸®´ª½º´Â Context ½ºÀ§ÄªÀ» ´ÙÀ½°ú °°Àº °æ¿ì¿¡ ÀÏÀ¸Å³¼ö ÀÖ½À´Ï´Ù. ½Ã°£ÀÚ¿øÀº ÀÌ·¯ÇÑ Context ½ºÀ§Äª¹®¸Æ¿¡¼­ ½Ã°£¿ÀÂ÷°¡ ¹ß»ýÇÒ¼ö Àֱ⠶§¹®¿¡ ¹Ýµå½Ã´Â ¾Æ´ÏÁö¸¸ ¼³°è½Ã¿¡ °í·ÁÇϸé ÁÁ½À´Ï´Ù.
    • sleep, usleep, nanosleep µîÀÇ delay°è¿­ ÇÔ¼ö
    • open, close, read, write, select, µîÀÇ systemcall ÇÔ¼öµé
    • sched_yield ÇÔ¼ö (º»·¡ºÎÅÍ ÀÌ ÇÔ¼ö´Â °­Á¦·Î Context ½ºÀ§ÄªÀ» ÀÏÀ¸Å°µµ·Ï ÀǵµÇÏ´Â ÇÔ¼öÀÔ´Ï´Ù.)
    • Timer interrupt¸¦ Æ÷ÇÔÇÑ ¸ðµç Interrupt ÁøÀÔÁ¡
    • ¸¸¾à ´ÙÀ½°ú °°ÀÌ ¹«ÇÑ·çÇÁ³»¿¡ À§ÀÇ Context Á¶°Ç°ü·Ã ÇÔ¼öÈ£ÃâÀÌ ¾ø´Ù¸é Context ½ºÀ§ÄªÀº ¿À·ÎÁö Interrupt ½ÃÁ¡¿¡¼­¸¸ ¹ß»ýÇÏ¿© ½Ã½ºÅÛÀÌ ±²ÀåÀÌ ´À·ÁÁú¼ö ÀÖ½À´Ï´Ù.
      for(;;);
    • ½Ã½ºÅÛÀÌ ´À·ÁÁö´Â°ÍÀ» ¸·±â À§Çؼ­ À§ÀÇ °æ¿ì´Â ´ÙÀ½°ú °°ÀÌ Á¶Ä¡ÇØ¾ß ÇÕ´Ï´Ù.
      #define HZ 100
      for(;;)usleep((HZ/1000) * 1000); /* ÀÌ °æ¿ì HZ»ó¼ö¿¡ µû¸¥ ÃÖÀûÀÇ
      sleepÀ» Áִ°ÍÀÌÁö¸¸ ±×³É usleep(10000) À¸·Î Çصµ ¹«°üÇÕ´Ï´Ù. */
  • Á¤¹Ð¼ºÀÌ ¿ä±¸µÇ´Â TimerÀÚ¿øÀÌ ÇÊ¿äÇÏ´Ù¸é Posix timerµµ °ËÅäÇÒ¸¸ÇÕ´Ï´Ù. ÀÌ°ÍÀº ¼³Á¤ÇÑ Áֱ⸦ ±âÁØÀ¸·Î Á¤È®È÷ TickÀ» ¹ß»ýÇϵµ·Ï ÇÒ¼ö ÀÖ½À´Ï´Ù.
    /*
      Copyright (C) JAEHYUK CHO
      All rights reserved.
      Code by JaeHyuk Cho <mailto:minzkn@minzkn.com>
    */

    #include <sys/types.h>
    #include <sys/time.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <signal.h>
    #include <time.h>
    #include <unistd.h>
    #include <errno.h>

    #include <pthread.h>

    #define def_mztimer_realtime_signal SIGRTMIN
        
    static long g_mztimer_interval_usec;

    static void mztimer_handler(int s_signal, siginfo_t *s_siginfo, void *s_user_context)
    {
        static unsigned int s_tick = 0;
        timer_t *s_timer_id_ptr;
        int s_overrun_count;

        (void)s_signal;
        (void)s_siginfo;
        (void)s_user_context;

        s_timer_id_ptr = (timer_t *)s_siginfo->si_value.sival_ptr;
        s_overrun_count = timer_getoverrun(*s_timer_id_ptr);
        if(s_overrun_count == (-1)) {
            s_overrun_count = 0;
        }

        (void)fprintf(stdout, "tick=%u, overrun_count=%d", s_tick, s_overrun_count);

    #if 1L /* DEBUG: compare with system time */
        do {
            static unsigned long long s_start_time_usec = 0ull;
            unsigned long long s_current_time_usec;
            struct timeval s_timeval;
            unsigned long long s_duration_usec, s_diff_usec;

            s_duration_usec = s_tick * g_mztimer_interval_usec;

            (void)gettimeofday(&s_timeval, NULL);
            s_current_time_usec = (s_timeval.tv_sec * 1000000) + s_timeval.tv_usec;
            if(s_start_time_usec == 0ull) {
                s_start_time_usec = s_current_time_usec;
            }
            s_current_time_usec -= s_start_time_usec;

            if(s_duration_usec > s_current_time_usec) {
                s_diff_usec = s_duration_usec - s_current_time_usec;
            }
            else {
                s_diff_usec = s_current_time_usec - s_duration_usec;
            }

            fprintf(stdout, ", real=%llu.%03llu, diff=%llu.%llu",
                s_current_time_usec / 1000ull,
                s_current_time_usec % 1000ull,
                s_diff_usec / 1000ull,
                s_diff_usec % 1000ull);
        }while(0);
    #endif

        (void)fprintf(stdout, "\n");

        s_tick += 1 + s_overrun_count;
    }
      
    static void *mztimer_thread(void *s_argument)
    {
        static timer_t s_timer_id;
        struct sigevent s_sigevent;
        struct itimerspec s_itimerspec;
        sigset_t s_mask;
        struct sigaction s_sigaction;
        clockid_t s_clock_id = CLOCK_REALTIME;

        /* establish handler for timer signal */
        s_sigaction.sa_flags = SA_SIGINFO;
        s_sigaction.sa_sigaction = mztimer_handler;
        sigemptyset(&s_sigaction.sa_mask);
        if(sigaction(def_mztimer_realtime_signal, &s_sigaction, NULL) == (-1)) {
            return(NULL);
        }

        /* block timer signal temporarily */
        sigemptyset(&s_mask);
        sigaddset(&s_mask, def_mztimer_realtime_signal);
        if(sigprocmask(SIG_SETMASK, &s_mask, NULL) == (-1)) {
            return(NULL);
        }

        /* create timer */
        s_sigevent.sigev_notify = SIGEV_SIGNAL;
        s_sigevent.sigev_signo = def_mztimer_realtime_signal;
        s_sigevent.sigev_value.sival_ptr = &s_timer_id;
        if(timer_create(s_clock_id, &s_sigevent, &s_timer_id) == (-1)) {
            return(NULL);
        }

        /* start the timer */
        s_itimerspec.it_value.tv_sec = g_mztimer_interval_usec / 1000000l;
        s_itimerspec.it_value.tv_nsec = (g_mztimer_interval_usec % 1000000l) * 1000l;
        s_itimerspec.it_interval.tv_sec = s_itimerspec.it_value.tv_sec;
        s_itimerspec.it_interval.tv_nsec = s_itimerspec.it_value.tv_nsec;
        if(timer_settime(s_timer_id, 0, &s_itimerspec, NULL) == (-1)) {
            return(NULL);
        }
      
        /* unlock the timer signal */
        if(sigprocmask(SIG_UNBLOCK, &s_mask, NULL) == (-1)) {
            return(NULL);
        }

        for(;;) {
            pause();
        }

        return(NULL);
    }

    int mztimer_start(long s_interval_usec)
    {
        pthread_t s_thread_handle;
        sigset_t s_mask;

        g_mztimer_interval_usec = s_interval_usec;

        if(pthread_create(&s_thread_handle, NULL, mztimer_thread, NULL) == (-1)) {
            return(-1);
        }
        (void)pthread_detach(s_thread_handle);
        
        sigemptyset(&s_mask);
        sigaddset(&s_mask, def_mztimer_realtime_signal);
        (void)sigprocmask(SIG_BLOCK, &s_mask, NULL);

        return(0);
    }

    int main(void)
    {
        (void)mztimer_start(1000l);

        for(;;) {
            
            sleep(1);
            
            (void)fprintf(stdout, "\x1b[1;33msleep loop\x1b[0m\n");
        }
        

        return(EXIT_SUCCESS);
    }

    /* End of source *

ID
Password
Join
The person you rejected yesterday could make you happy, if you say yes.


sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2015-02-06 16:37:23
Processing time 0.0154 sec