· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
Apache 2.0 Thread Safety Issues


Copyright 2006 The Apache Software Foundation. Licensed under the [http]Apache License, Version 2.0

Korean Translator: ±èÁ¤±Õ <http://oops.org>

¹ø¿ªº» Âü°í »çÇ×

  • ÀÌ ¹®¼­ÀÇ ¹ø¿ª °á°ú¹°·Î ÀÎÇÏ¿© ¹ß»ýÇÏ´Â ¹®Á¦¿¡ ´ëÇÏ¿© Ã¥ÀÓÀ» ÁöÁö ¾Ê½À´Ï´Ù.
  • ÀÌ ¹®¼­ÀÇ ¹ø¿ª¹°Àº ¿ø¹®ÀÇ ÀúÀ۱ǿ¡ ÀÇ°ÅÇÏ¿© ¼öÁ¤ ¹èÆ÷µÉ ¼ö ÀÖ½À´Ï´Ù.
  • ÀÌ ¹®¼­ÀÇ ¿øº»Àº http://httpd.apache.org/docs/2.2/developer/thread_safety.html ÀÔ´Ï´Ù.
  • ªÀº ÇÁ·Î±×·¡¹Ö Áö½ÄÀ¸·Î ¹ø¿ªÀ» ÇÏ¿´±â ¶§¹®¿¡ ¿À¿ªÀÌ ÀÖÀ» ¼ö ÀÖ½À´Ï´Ù.


Apache 2.0 ¿¡¼­ ¾î¶² ¾²·¹µå mpm À» »ç¿ëÇÒ °æ¿ì, Apache ¿¡¼­ È£ÃâµÇ´Â ¸ðµç ÇÔ¼ö°¡ thread safe ÇØ¾ß ÇÏ´Â °ÍÀº »ó´çÈ÷ Áß¿äÇÑ ÀÏÀÔ´Ï´Ù. 3th party extension ÀÌ ¸µÅ©(link)µÇ¾úÀ» °æ¿ì, ¼­¹ö°¡ thread safe ÇÑ °á°ú¸¦ °¡Áø´Ù°í ¸»Çϱâ´Â ÈûÀÌ µì´Ï´Ù. ÀÌ ¹®Á¦´Â °úÁßÇÑ ·Îµå°¡ °É·Á¾ß ÇÏ°í, ¾î¶² »óÅ¿¡¼­ ³ªÅ¸³¯Áö ¸ð¸£´Â ¹Ì¹¦ÇÑ race condition °ú °°ÀÌ ¹ß»ýÇϱ⠶§¹®¿¡, ÀϹÝÀûÀ¸·Î ÀϽÃÀûÀÎ Å×½ºÆ®·Î´Â thread safe ÇÏ´Ù°í ¸»ÇÒ ¼ö´Â ¾ø½À´Ï´Ù.

1. Àü¿ª º¯¼ö¿Í Á¤Àû º¯¼ö


¸ðµâÀ» ÀÛ¼ºÇÏ·Á°í Çϰųª, ¸ðµâ ¶Ç´Â 3rd party ¶óÀ̺귯¸®°¡ thread safe ÇÏ´Ù°í °áÁ¤À» ÇÏ·Á ÇÒ ¶§, À¯ÀÇÇÒ ÀϵéÀÌ ÀÖ½À´Ï´Ù.

¸ÕÀú, °¢ °³º° thread °¡ ÀڽŸ¸ÀÇ ÇÁ·Î±×·¥ counter, stack, register ¸¦ °¡Áö°í ÀÖ´Â thread ¸ðµ¨ÀÎÁö È®ÀÎÇÒ ÇÊ¿ä°¡ ÀÖ½À´Ï´Ù. ·ÎÄà º¯¼öµéÀº stack ¿¡ ÀúÀåÀÌ µÇ±â ¶§¹®¿¡ ¹®Á¦°¡ ¾ø½À´Ï´Ù. ÇÏÁö¸¸, ¾î¶² Á¤Àû º¯¼ö³ª Àü¿ª º¯¼ö´Â ÁÖÀÇÇؾßÇÒ ÇÊ¿ä°¡ ÀÖ½À´Ï´Ù. ÀÌ´Â Àý´ëÀûÀ¸·Î Á¤Àû ¶Ç´Â Àü¿ª º¯¼ö¸¦ »ç¿ëÇÏÁö ¸»¾Æ¾ß ÇÑ´Ù´Â °ÍÀº ¾Æ´Õ´Ï´Ù. ¾î¶² º¯¼ö°¡ ¸ðµç thread ¿¡ ¿µÇâÀ» ¹ÌÄ¡±â¸¦ ¿øÇÏ´Â °æ¿ì°¡ ÀÖÀ» ¼ö ÀÖ½À´Ï´Ù. ÇÏÁö¸¸ ÀϹÝÀûÀ¸·Î ´ç½ÅÀÇ Äڵ尡 thread safe Çϱ⸦ ¹Ù¶õ´Ù¸é, ÀÌ º¯¼ö¸¦ Á¤Àû/Àü¿ª º¯¼ö·Î »ç¿ëÇÏ´Â °ÍÀ» ÇÇÇÏ´Â °ÍÀÌ ÁÁ½À´Ï´Ù.

ÇÁ·Î±×·¥ Àüü¿Í ¸ðµç thrad ¿¡¼­ Á¢±ÙÀ» ÇÒ ÇÊ¿ä°¡ ÀÖ´Â Àü¿ª º¯¼ö°¡ ÀÖÀ» °æ¿ì, ÀÌ º¯¼ö¸¦ ¾÷µ¥ÀÌÆ® ÇÔ¿¡ ÀÖ¾î ´ë´ÜÈ÷ ÁÖÀÇÇØ¾ß ÇÕ´Ï´Ù. ¿¹¸¦ µé¾î, counter ¸¦ Áõ°¡ ½ÃÅ°´Â º¯¼ö¶ó¸é, ´Ù¸¥ thread ¿¡ race condition À» ÇÇÇϱâ À§ÇÏ¿© ÃÖ¼ÒÇÑÀ¸·Î(atomically) Áõ°¡¸¦ ½ÃÄÑ¾ß ÇÒ ¼öµµ ÀÖ½À´Ï´Ù. ´ç½ÅÀº mutex (mutual exclustion)¸¦ ÀÌ¿ëÇÏ¿© ÀÌ°ÍÀ» ÇÒ ¼ö ÀÖ½À´Ï´Ù. mutex ¿¡ ¶ôÀ» °É°í, ÇöÀç °ªÀ» Àаí, ±× º¯¼ö¸¦ Áõ°¡ ½ÃŲ ÈÄ¿¡ ¾²°í, mutex ÀÇ ¶ôÀ» ÇØÁ¦ ÇϽʽÿÀ. °ªÀ» º¯°æÇϱ⸦ ¿øÇÏ´Â ´Ù¸¥ ¾î¶² thread ´Â º¯¼ö°¡ Ŭ¸®¾î µÉ ¶§±îÁö ¸ÕÀú mutex ¸¦ °Ë»çÇÏ°í ºí·° ½ÃÄÑ¾ß ÇÕ´Ï´Ù.

¸¸¾à APRÀ» »ç¿ëÇÏ°í ÀÖ´Ù¸é, apr_atomic_* ÇÔ¼ö¿Í apr_thread_mutex_* ÇÔ¼ö¸¦ ÂüÁ¶ ÇϽʽÿÀ.

2. errno


errno ´Â ¸¶Áö¸·À¸·Î ¹ß»ýÇÑ ¿¡·¯ÀÇ ¿¡·¯ ¹øÈ£¸¦ °¡Áö°í ÀÖ´Â Àü¿ª º¯¼ö ÀÔ´Ï´Ù. ÇϳªÀÇ ¾²·¹µå°¡ errno ¸¦ ¼³Á¤ÇÏ´Â low-level ÇÔ¼ö¸¦ È£ÃâÇÏ¿´°í, ´Ù¸¥ ¾²·¹µå°¡ ÀÌ º¯¼ö¸¦ ÂüÁ¶ ÇÏ¿´À» °æ¿ì, ÂüÁ¶ÇÑ ¾²·¹µå·Î ¿øÄ¡¾Ê´Â errno ¸¦ Àü´ÞÇÏ°Ô µË´Ï´Ù. ÀÌ ¹®Á¦¸¦ ÇØ°áÇϱâ À§ÇÏ¿©, ¸ðµâ°ú ¶óÀ̺귯¸®¿¡ _REENTRANT »ó¼ö¸¦ ¼±¾ðÇϰųª ¶Ç´Â ÄÄÆÄÀÏ ½Ã¿¡ -D_REENTRANT ¿É¼ÇÀ» ÁÖ½Ç ¼ö ÀÖ½À´Ï´Ù. ÀÌ »ó¼ö´Â errno ¸¦ per-thread º¯¼ö·Î ¸¸µé¾î ÁÖ¸ç, Äڵ带 Åõ¸íÇÏ°Ô ÇÒ ¼ö ÀÖ½À´Ï´Ù. ÀÌ »ó¼ö¸¦ ¼±¾ðÇÏ´Â °ÍÀº ´ÙÀ½°ú °°ÀÌ ÀÛµ¿À» Çϵµ·Ï ÇÕ´Ï´Ù:

#define errno (*(__errno_location()))

ÀÌ ÄÚµåÀÇ Àǹ̴ errono ¿¡ Á¢±ÙÀ» Çϸé, libc ¿¡¼­ Á¦°øµÇ´Â __errno_location() ÀÌ È£ÃâÀÌ µË´Ï´Ù. _REENTRANT ¸¦ ¼³Á¤Çϸé, µ¿µîÇÑ ±â´ÉÀ» °¡Áø *_r ÇÔ¼ö¸¦ Á¦°øÇÒ °æ¿ì °­Á¦·Î ÀÌ ÇÔ¼öµé·Î ÀçÁ¤ÀÇ ÇÕ´Ï´Ù. ±×¸®°í °¡²û ¾ÈÀüÇÑ ÇÔ¼ö È£ÃâÀ» À§ÇØ getc/pubc ¸ÅÅ©·Î¸¦ º¯°æÇϱ⵵ ÇÕ´Ï´Ù. _REENTRANT ¸¦ Ãß°¡ÇÏ´Â °Í ¿Ü¿¡ ÀÌ ¹®Á¦¿¡ ´ëÇÏ¿© ¿µÇâÀ» ¹ÌÄ¥¼ö ÀÖ´Â ½Éº¼·Î´Â _POSIX_C_SOURCE, _THREAD_SAFE, _SVID_SOURCE, _BSD_SOURCE µîÀÌ ÀÖ½À´Ï´Ù. ÀÌ °Í¿¡ ´ëÇؼ­´Â libc ¹®¼­¸¦ ÂüÁ¶ ÇϽʽÿÀ.

3. Common standard troublesome functions


thread safe ÇÏ°Ô ¸¸µé¾î¾ß ÇÒ »Ó ¾Æ´Ï¶ó ÀçÁøÀÔ(?..reentrant)ÀÌ °¡´É Çؾ߸¸ ÇÕ´Ï´Ù. strtok °¡ ¸íÈ®ÇÏ°Ô ÀÌ ¹®Á¦¸¦ °¡Áö°í ÀÖ½À´Ï´Ù. strtok °¡ ±â¾ïÀ» ÇÏ°í ÀÖ´Â ±¸ºÐÀÚ·Î strtok ¸¦ óÀ½ È£ÃâÀ» ÇÏ°í, °¢°¢ÀÇ ¼ö¹ÝµÇ´Â È£Ãâ¿¡ ´ÙÀ½ ÅäÅ«À» ¹ÝȯÇÏ°Ô µË´Ï´Ù. (Àǹ̸¦ Àß ¸ð¸£°Ú±º¿ä..You call it the first time with your delimiter which it then remembers and on each subsequent call it returns the next token.) tokenizing »óŸ¦ °ü¸®Çϱâ À§ÇÏ¿© ÇÔ¼ö°¡ ÀÚ½ÅÀÇ Á¤Àû ½ºÅ丮Áö ´ë½Å¿¡ »ç¿ëÇϱâ À§ÇÏ¿© ÇÒ´çµÈ char * ¸¦ Æ÷ÇÔÇÑ Æ¯º°ÇÑ ÀÎÀÚ¸¦ °¡Áø strtok_r() À̶ó°í ºÒ¸®´Â ÀçÁøÀÔ ¹öÀüÀÇ ÇÔ¼ö¸¦ °¡Áö°í ÀÖ½À´Ï´Ù. APR À» »ç¿ëÇÑ´Ù¸é, apr_strtok() ¸¦ »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù.

crypt() ¿ª½Ã ÀçÁøÀÔ(reentrant)ÀÌ µÇÁö ¾Ê´Â ÇÔ¼ö ÁßÀÇ Çϳª ÀÔ´Ï´Ù. ±×·¯¹Ç·Î ¶óÀ̺귯¸®¿¡ ÀÖ´Â ÀÌ ÇÔ¼ö¸¦ °¡·ÎÁú·¯¼­ È£ÃâÇÏ´Â °ÍÀº ÇÇÇØ¾ß ÇÕ´Ï´Ù. ¾î¶² ½Ã½ºÅÛ¿¡¼­´Â ÀçÁøÀÔÀÌ °¡´ÉÇϱ⠶§¹®¿¡, Ç×»ó ¹®Á¦°¡ µÇ´Â °ÍÀº ¾Æ´Õ´Ï´Ù. If your system has crypt_r() chances are you should be using that, or if possible simply avoid the whole mess by using md5 instead.


4. Common 3rd Party Libraries


´ÙÀ½Àº Apache ÀÇ 3th party ¸ðµâÀÌ »ç¿ëÇÏ°í ÀÖ´Â system ¶óÀ̺귯¸®ÀÇ ¸®½ºÆ® ÀÔ´Ï´Ù. ´ç½ÅÀÌ »ó¿ëÇÏ´Â ¸ðµâÀÌ ÀáÀç°ÅÀ¸·Î ¾ÈÀüÇÏÁö ¾ÊÀº ¶óÀ̺귯¸®¸¦ »ç¿ëÇÏ°í ÀÖ´Ù¸é, ldd(1) ³ª nm(1) °ú °°Àº µµ±¸¸¦ »ç¿ëÇÏ¿© È®ÀÎÀ» ÇÒ ¼ö ÀÖ½À´Ï´Ù. ´ÙÀ½ÀÇ ¿¹´Â PHP ¸¦ ÀÌ¿ëÇÏ¿© È®ÀÎÇÏ´Â °ÍÀÔ´Ï´Ù:

% ldd libphp4.so
libsablot.so.0 => /usr/local/lib/libsablot.so.0 (0x401f6000)
libexpat.so.0 => /usr/lib/libexpat.so.0 (0x402da000)
libsnmp.so.0 => /usr/lib/libsnmp.so.0 (0x402f9000)
libpdf.so.1 => /usr/local/lib/libpdf.so.1 (0x40353000)
libz.so.1 => /usr/lib/libz.so.1 (0x403e2000)
libpng.so.2 => /usr/lib/libpng.so.2 (0x403f0000)
libmysqlclient.so.11 => /usr/lib/libmysqlclient.so.11 (0x40411000)
libming.so => /usr/lib/libming.so (0x40449000)
libm.so.6 => /lib/libm.so.6 (0x40487000)
libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0x404a8000)
libjpeg.so.62 => /usr/lib/libjpeg.so.62 (0x404e7000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x40505000)
libssl.so.2 => /lib/libssl.so.2 (0x40532000)
libcrypto.so.2 => /lib/libcrypto.so.2 (0x40560000)
libresolv.so.2 => /lib/libresolv.so.2 (0x40624000)
libdl.so.2 => /lib/libdl.so.2 (0x40634000)
libnsl.so.1 => /lib/libnsl.so.1 (0x40637000)
libc.so.6 => /lib/libc.so.6 (0x4064b000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)

°Ô´Ù°¡, ÀÌ ¶óÀ̺귯¸®µé ¿Ü¿¡µµ ¸ðµâ¿¡ Á¤ÀûÀ¸·Î ¸µÅ©µÈ ¶óÀ̺귯¸®°¡ ÀÖ´Ù¸é ÀÌ°Í ¿ª½Ã È®ÀÎÇØ º¸¾Æ¾ß ÇÕ´Ï´Ù. °¢ ¸ðµâÀÇ °³º° ½Éº¼À» º¸±â À§Çؼ­´Â nm(1)À» »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù.

5. Library List


ÀÌ ¸®½ºÆ®¿¡ Ãß°¡ÇÏ¿©¾ß Çϰųª ¼öÁ¤ÇØ¾ß ÇÒ »çÇ×ÀÌ ÀÖ´Ù¸é dev@httpd.apache.org ·Î ¿¬¶ôÀ» ÁֽʽÿÀ.


¶óÀ̺귯¸® ¹öÀü Thread Safe? ºñ°í
ASpell/PSpell ?
Berkeley DB 3.x, 4.x Yes Thread °£ÀÇ °øÀ¯ ¿¬°á(sharing conenction)¿¡ ´ëÇÏ¿© ÁÖÀÇÇØ¾ß ÇÔ.
bzip2 Yes low-level, high-level API ¸ðµÎ thread safe ÇÔ. ÇÏÁö¸¸, high-level API ¸¦ »ç¿ëÇÔ¿¡ ÀÖ¾î errno ¿¡ Á¢±ÙÀ» ÇÒ ¶§ thread safe Çϵµ·Ï »ç¿ëÇØ¾ß ÇÔ.
cdb ?
C-Client Perhaps c-client uses strtok() and gethostbyname() which are not thread-safe on most C library implementations. c-client's static data is meant to be shared across threads. If strtok() and gethostbyname() are thread-safe on your OS, c-client may be thread-safe.
cpdflib ?
libcrypt ?
Expat Yes Need a separate parser instance per thread
FreeTDS ?
FreeType ?
GD 1.8.x ?
GD 2.0.x ?
gdbm No Errors returned via a static gdbm_error variable
ImageMagick 5.2.2 Yes ImageMagick docs claim it is thread safe since version 5.2.2 (see Change log).
Imlib2 ?
libjpeg v6b ?
libmysqlclient Yes Use mysqlclient_r library variant to ensure thread-safety. For more information, please read http://www.mysql.com/doc/en/Threaded_clients.html.
Ming 0.2a ?
Net-SNMP 5.0.x ?
OpenLDAP 2.1.x Yes Use ldap_r library variant to ensure thread-safety.
OpenSSL 0.9.6g Yes Requires proper usage of CRYPTO_num_locks, CRYPTO_set_locking_callback, CRYPTO_set_id_callback
liboci8 (Oracle 8+) 8.x,9.x ?
pdflib 5.0.x Yes PDFLib docs claim it is thread safe; changes.txt indicates it has been partially thread-safe since V1.91: http://www.pdflib.com/products/pdflib/index.html.
libpng 1.0.x ?
libpng 1.2.x ?
libpq (PostgreSQL) 7.x Yes Don't share connections across threads and watch out for crypt() calls
Sablotron 0.95 ?
zlib 1.1.4 Yes Relies upon thread-safe zalloc and zfree functions Default is to use libc's calloc/free which are thread-safe.



ID
Password
Join
Take care of the luxuries and the necessities will take care of themselves.


sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2010-01-14 14:29:44
Processing time 0.0117 sec