· 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
Some men are discovered; others are found out.


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.0099 sec