 | |
ÀλýÀº ´ÙÀ½ µÎ°¡Áö·Î ¼º¸³µÈ´Ù. ÇÏ°í ½ÍÁö¸¸ ÇÒ ¼ö ¾ø´Ù. ÇÒ ¼ö ÀÖÁö¸¸ ÇÏ°í ½ÍÁö ¾Ê´Ù. - ±«Å× -
¾²·¹µåÇ® ÀÛ¼º Posted on 2002/12/23
Topic: ±âº»¶óÀ̺귯¸®
|
¾²·¹µå Ç®Àº ¿¬°á/Á¾·á°¡ ÀÚÁÖÀϾ´Â À¥¼¹ö¿Í
°°Àº ¹Ù»Û ¼¹ö¿¡°Ô ÀÖ¾î¼ È¿À²ÀûÀΠŬ¶óÀÌ¾ðÆ® ¿¬°á
󸮸¦ À§Çؼ »ç¿ëÇÏ´Â ÇÁ·Î±×·¡¹Ö ±â¹ýÀÌ´Ù.
À̹ø¿¡´Â ¾²·¹µåÇ®À» ÀÌ¿ëÇÑ ¾îÇø®ÄÉÀÌ¼Ç Á¦ÀÛ¹æ¹ý¿¡
´ëÇØ¼ ¾Ë¾Æº¸µµ·Ï ÇϰڴÙ.
Thread Pooling| 교정 과정 |
|---|
| 교정 0.7 | 2003³â 1¿ù 24ÀÏ 14½Ã | | | Thread Pool ±¸¼ºµµ À̹ÌÁö Ãß°¡,¹®¼ È÷½ºÅ丮 Ãß°¡ |
pool ÀÇ »çÀüÀûÀÎ ¶æÀ» ã¾Æº¸¸é ¿¬¸ø, Àú¼öÁö, ¼ö¿µÀå Ç® µî
"¹«¾ùÀ» ´ã¾Æ³õ´Â" ÀÇ ¶æÀ» °¡Áø´Ù.
ÀÌ´ë·Î ÇØ¼®ÇÏÀÚ¸é Thread Pooling À̶õ ¾²·¹µå¸¦
´ã¾Æ ³õ´Â ¿ë±â(¸Þ¸ð¸®°¡ µÉ°ÍÀÌ´Ù) ¸¦ ¶æÇϸç, ÇÁ·Î±×·¡¹Ö Ãø¸é¿¡¼
ÇØ¼®ÇÏÀÚ¸é, "¹Ì¸® ¾²·¹µå¸¦ ÇÒ´ç½ÃÄÑ ³õ´Â±â¹ý" À» ¶æÇÑ´Ù.
±×·¸´Ù¸é ¾²·¹µå¸¦ ¹Ì¸® ÇÒ´ç½ÃÄÑ ³õ´Â ÀÌÀ¯¿¡ ´ëÇØ¼ »ý°¢Çغ¸ÀÚ,
Áö±Ý±îÁö ÀÌ »çÀÌÆ®¿¡¼ ´Ù·ç¾ú´ø ¾²·¹µåÇÁ·Î±×·¡¹Ö ±â¹ýÀº
±âº»ÀûÀ¸·Î fork ¹æ½Ä°ú ¸Å¿ì ºñ½ÁÇϸç, ¾²·¹µå¸¦ »ý¼º½ÃÄÑ¾ß µÉ
Çʿ䰡 ÀÖÀ»¶§ pthread_create(3)µîÀÇ ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© »õ·Î¿î ÀÛ¾÷¾²·¹µå¸¦
»ý¼º½ÃŰ´Â ¹æ½ÄÀ» »ç¿ëÇß´Ù. º¸Åë ¾²·¹µåÇÁ·Î±×·¡¹ÖÀº ³×Æ®¿÷ ÇÁ·Î±×·¡¹Ö½Ã
ÁÖ·Î »ç¿ëµÊÀ¸·Î accept(2) ·Î ¿¬°áÀ» ±â´Ù¸®´Ù°¡ ¿¬°áÀÌ ¸¸µé¾îÁö¸é
accept ¿¡¼ ³Ñ¾î¿Â ¼ÒÄÏ Áö½ÃÀÚ¸¦ ÀÎÀÚ·Î ÇÏ´Â ¾²·¹µå¸¦ »ý¼ºÇß´Ù.
ÀÌ·¯ÇÑ ¹æ½Ä - ¿äûÀÌ ÀÖÀ»¶§ ¾²·¹µå¸¦ »ý¼º½ÃŰ´Â - ÀÇ ¾²·¹µå ÇÁ·Î±×·¡¹Ö±â¹ýÀº
´ëºÎºÐÀÇ ÀÛ¾÷À» ó¸®Çϱ⿡ ÃæºÐÈ÷ È¿À²ÀûÀ̸ç, ºü¸£±äÇÏÁö¸¸ Ŭ¶óÀÌ¾ðÆ®·Î ºÎÅÍÀÇ
¿¬°á°ú Á¾·á°¡ ¸Å¿ì ¹Ù»Ú°Ô ÀϾ´Â ¼¹öÀÇ °æ¿ì, °è¼ÓÀûÀ¸·Î ¾²·¹µå¸¦ »ý¼ºÇϰí
Á¾·áÇØ¾ß ÇÏ´Â ºñ¿ëÀ» ¹«½ÃÇÒ¼ö ¾ø°Ô µÈ´Ù. ¾²·¹µå°¡ ºñ·Ï fork()¿¡ ºñÇØ¼
»ý¼º°ú ¼Ò¸ê½Ã¿¡ ÈξÀ ÀûÀº ºñ¿ëÀ» ¼Ò¸ðÇÑ´Ù°í´Â ÇÏÁö¸¸, ÀÌ°Ç ¾îµð±îÁö³ª
»ó´ëÀûÀÎ °ÍÀ¸·Î ½Ç»óÀº ²Ï ¸¹Àº ½Ã°£°ú ºñ¿ëÀ» ¼ÒºñÇÏ´Â ÀÛ¾÷ÀÌ´Ù. ƯÈ÷
Linux ¿¡¼ÀÇ Pthread ÀÇ °æ¿ì clone(2)¸¦ ÀÌ¿ëÇÑ ±¸ÇöÀÓÀ¸·Î ´õ¿í´õ ¸¹Àº
ºñ¿ëÀ» ¼ÒºñÇÏ°Ô µÈ´Ù.
Thread Pooling Àº ÀÌ·¯ÇÑ ¹Ýº¹ÀûÀÎ ¾²·¹µåÀÇ »ý¼º/¼Ò¸ê¿¡ ÀÇÇÑ ºñÈ¿À²ÀûÀÎ Ãø¸éÀ»
¾ø¾Ö°íÀÚ ÇÏ´Â ¸ñÀûÀ¸·Î ¸¸µé¾îÁø ÇÁ·Î±×·¡¹Ö ±â¹ýÀÌ´Ù.
°³³äÀûÀ¸·Î º¸ÀÚ¸é Thread Pool À» ±¸¼ºÇÏ´Â°Ç ¸Å¿ì °£´ÜÇÏ´Ù.
»ý¼ºÇϰíÀÚ ÇÏ´Â Å©±â¸¸Å ptread_create() ÇÔ¼ö¸¦ µ¹¸®¸é µÇ±â ¶§¹®ÀÌ´Ù.
ÇÏÁö¸¸ ÀÌ°Ç ¾îµð±îÁö³ª °³³äÀûÀÎ °ÍÀ¸·Î ´ëºÎºÐÀÇ °æ¿ì °¢°¢ÀÇ ¾²·¹µå¸¦
½ºÄÉÁ층 ÇØÁÖ¾î¾ß ÇÔÀ¸·Î, ¶§¿¡ µû¶ó¼´Â ±¸ÇöÀ» À§Çؼ ¸Å¿ì º¹ÀâÇÑ
ÇÁ·Î±×·¡¹Ö ±â¹ýÀ» µ¿¿øÇØ¾ß ÇÒ¶§µµ ÀÖ´Ù. °£´ÜÈ÷
À¥ ¼¹ö¸¦ Thread Pool ·Î ±¸ÇöÇÑ´Ù°í °¡Á¤À» ÇØº¸ÀÚ - º¸Åë À¥¼¹ö´Â
HTTP ÀÇ Æ¯¼º»ó ¿¬°á°ú/Á¾·á°¡ ºó¹øÇÏ°Ô ÀÏ¾î ³²À¸·Î ¾²·¹µåÇ®À» »ç¿ëÇÒ°æ¿ì
¸¹Àº ÀÌÀÍÀ» ¾òÀ»¼ö ÀÖ´Ù -, ¸¸¾à 100 °³ÀÇ Thread ¸¦ ¹Ì¸® »ý¼º½ÃÄ×°í,
°¢°¢ÀÇ Thread ´Â ÇϳªÀÇ Å¬¶óÀÌ¾ðÆ® ¿¬°áÀ» ó¸®ÇÑ´Ù°í °¡Á¤ÇßÀ»¶§,
main ¾²·¹µå´Â accept(2) ¸¦ ÅëÇØ¼ Ŭ¶óÀÌ¾ðÆ®¸¦ ¹Þ¾Æµé¿´À»¶§,
accept() ·Î ¸¸µé¾îÁø ¼ÒÄÏ ÁöÁ¤¹øÈ£¸¦ ¹Ì¸® ¸¸µé¾îÁø 100 °³ÀÇ ¾²·¹µåÁß
"³î°í" ÀÖ´Â ¾²·¹µå¿¡°Ô ³Ñ°ÜÁÖ¾î¾ß ÇÒ°ÍÀÌ´Ù. ±×·¯±â À§Çؼ´Â
main ¾²·¹µå¿¡¼ °¢°¢ÀÇ ¾²·¹µå »óŸ¦ À¯ÁöÇØ¼ Àû´çÇÑ ¾²·¹µå¿¡°Ô
ÆÄÀÏÁöÁ¤ÀÚ¸¦ ³Ñ°ÜÁà¾ß ÇÒ°ÍÀÌ´Ù.
±×³ª¸¶ À§ÀÇ °æ¿ì´Â ÇϳªÀÇ ¾²·¹µå°¡ ÇϳªÀÇ ¿¬°áÀ» ó¸®ÇÔÀ¸·Î ¾î·ÆÁö
¾Ê°Ô ±¸ÇöÇϰÚÁö¸¸, ¸¸¾à 100°³ÀÇ ¾²·¹µå°¡ ÀÖ°í, °Å±â¿¡ °¢°¢ÀÇ ¾²·¹µå°¡
10°³ ¾¿ÀÇ Å¬¶óÀÌ¾ðÆ® ¿¬°áÀ» ó¸®Çϵµ·Ï ±¸¼ºÇÑ´Ù¸é, °Å±â¿¡´Ù°¡ Àû´çÇÑ
·Îµå¹ë·±½Ì ±â´É ±îÁö Æ÷ÇÔ½Ã۰íÀÚ ÇÑ´Ù¸é, ±¸ÇöÀÌ ²Ï º¹ÀâÇØ Áú¼öµµ
ÀÖ´Ù.
À§´Â Thread Pool ÀÇ ´ë·«ÀûÀÎ ±¸Çö»óŸ¦ ±×¸²? À¸·Î ³ªÅ¸³½ °ÍÀÌ´Ù.
Thread Pool ¿¡ µé¾îÀÖ´Â °¢°¢ÀÇ ¾²·¹µå¸¦ °ü¸®Çϱâ À§Çؼ´Â
ÇʼöÀûÀ¸·Î °¢°¢ÀÇ ¾²·¹µåÀÇ »óŸ¦ °¡Áö°í ÀÖ´Â Schedul ÀڷᱸÁ¶ ¸¦
°¡Áö°í ÀÖ¾î¾ßÇÑ´Ù. ±×·¡¾ß¸¸ MAIN THREAD ¿¡¼ ¾²·¹µå »óŸ¦
È®ÀÎÇØ¼ Àû´çÇÑ ¾²·¹µå·Î ÀÛ¾÷ºÐ¹è°¡ °¡´ÉÇÒ°ÍÀ̱⠶§¹®ÀÌ´Ù.
- ½ÇÁ¦ Linux Ä¿³Îµµ °¢°¢ÀÇ task ÀÇ ½ºÄÉÁ층À» À§Çؼ task ±¸Á¶Ã¼¸¦
À¯ÁöÇÑ´Ù. -
ÀÌÁ¦ ±¸Çö¹æ½Ä¿¡ ´ëÇÑ ¹Ø±×¸²ÀÌ ³ª¿ÔÀ¸´Ï, ½ÇÁ¦·Î ±¸ÇöÀ» À§ÇÑ
ÇÁ·Î¼¼½º¸¦ ¸¸µé¾î º¸µµ·Ï ÇÏÀÚ. ÇÁ·Î¼¼½º´Â ½´µµÄÚµå·Î ±¸¼ºÀ»
Çϵµ·Ï ÇϰڴÙ. ³×Æ®¿÷ ¼¹ö ÀÛ¼ºÀ» ±âÁØÀ¸·Î ÇϰڴÙ.
½ºÄÉÁì°ü·Ã ÀڷᱸÁ¶
{
ÇöÀç ¿¬°áµÈ Ŭ¶óÀÌ¾ðÆ®¼ö
ÇöÀç ó¸®ÇØ¾ßµÉ Å¬¶óÀÌ¾ðÆ® ¼ÒÄÏÁö½ÃÀÚ
¾²·¹µåÇ®¿¡ ¸¸µé¾îÁø ¾²·¹µå »óÅ : ¾²·¹µåÇ® Å©±â¸¸ÅÀÇ ¹è¿
{
0 À̸é È޽ĻóÅÂ
1 À̸é ÀÛ¾÷»óÅÂ
ó¸®ÁßÀÎ ¼ÒÄÏÁö½ÃÀÚ
}
};
main ÇÔ¼ö½ÃÀÛ
{
¾Æ±Ô¸ÕÆ®·Î ¸î°³ÀÇ ¾²·¹µå¸¦ »ý¼ºÇÒÁö¸¦ ¹ÞÀ½
while(¾²·¹µå »ý¼º¼ö¸¸Å)
{
pthread_create ¸¦ ÀÌ¿ëÇØ¼ ¾²·¹µå »ý¼º
// Åë½Å¾²·¹µå ÇÔ¼ö
{
WAIT:
main ¾²·¹µå°¡ ±ú¿ì±æ ±â´Ù¸°´Ù.
¸¸¾à main ¾²·¹µå·Î ºÎÅÍ ±ú¿òÀÌ ÀÖ´Ù¸é
{
½ºÄÉÁì ÀڷᱸÁ¶->ÇöÀç ó¸®ÇØ¾ßµÉ ¼ÒÄÏÁö½ÃÀÚ ¸¦ Àоî¿Â´Ù.
½ºÄÉÁì ÀڷᱸÁ¶->ÀÚ½ÅÀÇ »óŸ¦ 1·Î ¼¼ÆÃÇÑ´Ù.
½ºÄÉÁì ÀڷᱸÁ¶->ó¸®ÁßÀÎ ¼ÒÄÏÁö½ÃÀÚ¸¦ ¼¼ÆÃÇÑ´Ù.
while(1)
{
Ŭ¶óÀÌ¾ðÆ®¿Í Åë½ÅÇÑ´Ù.
¸¸¾à ¿¡·¯°¡ ¹ß»ýÇϸé
{
½ºÄÉÁì ÀڷᱸÁ¶->ó¸®ÁßÀÎ ¼ÒÄÏÁö½ÃÀÚ¸¦ 0À¸·Î ¼¼ÆÃ
½ºÄÉÁì ÀڷᱸÁ¶->ÀÚ½ÅÀÇ »óŸ¦ 0À¸·Î ¼¼ÆÃ
½ºÄÉÁì ÀڷᱸÁ¶->ÇöÀç ¿¬°áµÈ Ŭ¶óÀÌ¾ðÆ®¼ö --;
goto WAIT:
}
}
}
}
}
// main ¾²·¹µå
while(1)
{
¸¸¾à accept ¸¦ ÅëÇØ¼ ¿¬°áÀÌ ¹ß»ýÇÑ´Ù¸é
{
½ºÄÉÁì°ü·Ã ÀڷᱸÁ¶->ÇöÀ翬°áµÈ Ŭ¶óÀÌ¾ðÆ®¼ö°¡ MAX ¸¦ ÃʰúÇÏÁö ¾Ê¾Ò´Ù¸é
{
½ºÄÉÁì°ü·Ã ÀڷᱸÁ¶->ÇöÀ翬°áµÈ Ŭ¶óÀÌ¾ðÆ®¼ö ++;
½ºÄÉÁì°ü·Ã ÀڷᱸÁ¶->ÇöÀçó¸®ÇØ¾ßµÉ Å¬¶óÀÌ¾ðÆ® ¼ÒÄÏÁö½ÃÀÚ = accept();
½ºÄÉÁÙ°ü·Ã ÀڷᱸÁ¶->¾²·¹µåÇ®¿¡ ¸¸µé¾îÁø ¾²·¹µå»óÅ °¡ 0ÀÎ
¾²·¹µå¸¦ ã¾Æ¼ ÇØ´ç ¾²·¹µå¸¦ ±ú¿î´Ù.
}
±×·¸Áö ¾Ê°í ÃʰúÇßÀ»°æ¿ì
{
Ŭ¶û¸®¾ðÆ®¿¡°Ô ¿¡·¯¸Þ½ÃÁö¸¦ Àü¼ÛÇÑ´Ù.
}
}
}
}
|
±¸ÇöÀº ±¸ÇöÇÏ´Â ÇÁ·Î±×·¡¸Ó°¡ »óȲ¿¡ µû¶ó¼ ¼±ÅÃÇϱ⠳ª¸§À̱ä ÇÏÁö¸¸
º¸ÅëÀº À§ÀÇ ¹æ¹ýÀ» ±âº»À¸·Î ÇØ¼, ¾à°£ÀÇ º¯°æÀ» °¡ÇÏ´Â Á¤µµ°¡
µÉ°ÍÀÌ´Ù. À§ÀÇ ½´µµÄڵ带 º¸¸é main ¾²·¹µå¿¡¼ accept ¸¦ ¹ÞÀ¸¸é
È޽ĻóÅ¿¡ ÀÖ´Â ¾²·¹µå¸¦ ±ú¿î´Ù°í µÇ¾îÀִµ¥, À̶§ ±ú¿ì±â
À§Çؼ´Â ¾²·¹µå Á¶°Çº¯¼ö¸¦ »ç¿ëÇÏ¸é µÉ°ÍÀÌ´Ù.
±×·¸´Ù¸é ½ºÄÉÁì°ü·Ã ÀڷᱸÁ¶´Â ¾î¶»°Ô ±¸ÇöÇÏ´Â°Ô ½¬¿î¹æ¹ýÀÎÁö
»ý°¢Çغ¸µµ·Ï ÇÏÀÚ. ±¸ÇöÇÏ´Â ¹æ¹ýÀº ÇÁ·Î±×·¡¸Ó ¸¾À̰ÚÁö¸¸,
ÇÊÀÚ°¡ ±¸ÇöÇϰíÀÚ ÇÑ´Ù¸é multimap À» ÀÌ¿ëÇØ¼ ±¸ÇöÇÒ°ÍÀÌ´Ù.
ÀÌ ÀڷᱸÁ¶´Â ¾Æ¸¶ ´ÙÀ½°ú °°À»°ÍÀÌ´Ù.
// ¾²·¹µå Á¤º¸ ±¸Á¶Ã¼
struct ph
{
int sockfd; // ó¸®ÁßÀÎ ¼ÒÄÏÁöÁ¤¹øÈ£
int index_num; // ¾²·¹µåÀÇ À妽º ¹øÈ£
};
// ¾²·¹µå ±¸Á¶Ã¼ MAP
multimap<int, struct ph> phinfo;
struct schedul_info
{
int client_num; // ÃÑ ¿¬°áÁßÀΠŬ¶óÀÌ¾ðÆ®¼ö
int current_sockfd; // °¡ÀåÃÖ±Ù¿¡ ¿¬°áµÈ ¼ÒÄÏÁöÁ¤¹øÈ£
phinfo mphinfo; // ¾²·¹µå ±¸Á¶Ã¼ map
}
|
¸ÖƼ¸ÊÀÇ key ´Â ¾²·¹µåÀÇ È°¼ºÈ ¿©ºÎ·Î 1 ȤÀº 0ÀÌ µÈ´Ù.
±×¸®°í value ´Â ÇØ´ç ¾²·¹µå Á¤º¸°¡ µÉ°ÍÀÌ´Ù.
ÀÌ·¸°Ô ¸ÖƼ¸ÊÀ¸·Î ¸¸µçÀÌÀ¯´Â °£´ÜÇÏ´Ù. ¸ÖƼ¸ÊÀº Á¤·Ä¿¬°ü ÄÁÅ×ÀÌ³Ê ÀÓÀ¸·Î
key ¸¦ ±âÁØÀ¸·Î ÀÚµ¿ÀûÀ¸·Î Á¤·ÄÀÌ µÉ°ÍÀÌ´Ù.
¸¸¾à ù¹øÂ° ¾²·¹µå°¡ ó¸®Áß(1)·Î º¯°æµÇ¾ú´Ù¸é ÀÌ ¿ø¼Ò´Â
multimap ÀÇ °¡Àå µÚ·Î Á¤·ÄÀÌ µÉ°ÍÀÌ´Ù. ±×·³À¸·Î ¿ì¸®´Â
Ŭ¶óÀ̾ðÆ®ÀÇ ¼ö°¡ ÃÑ¿¬°á°¡´ÉÇÑ Å¬¶óÀÌ¾ðÆ®¼ö(Thread Pool ¿¡ »ý¼ºµÈ ¾²·¹µå¼ö)
¸¦ ÃʰúÇÏÁö ¾Ê´ÂÇÑ phinfo.begin() À¸·Î °¡Á®¿Â ¾²·¹µå´Â È޽ĻóÅÂ(0) À̶ó´Â°É
¹ÏÀ»¼ö ÀÖ°Ô µÈ´Ù. ´Ù½Ã ¸»Çؼ º¹ÀâÇØ¼ ¾²·¹µå»óŰ¡ 0ÀÎÁö 1ÀÎÁö óÀ½ºÎÅÍ
°Ë»çÇÒ Çʿ䰡 ¾ø´Ù´Â ¶æÀÌ´Ù.
1 2 3 4 5 6 7 99 100 : ¾²·¹µå ¹øÈ£
+-+-+-+-+-+-+-+---+-+-+
|0|0|0|0|0|0|0|...|0|0|
+-+-+-+-+-+-+-+---+-+-+
--> ¿¬°áÀÌ µé¾î¿Ô´Ù¸é
1 2 3 4 5 6 7 99 100 : ¾²·¹µå ¹øÈ£
+-+-+-+-+-+-+-+---+-+-+
|1|0|0|0|0|0|0|...|0|0|
+-+-+-+-+-+-+-+---+-+-+
| |
+----------->-------+
°¡Àå µÚ·Î ÀÚµ¿À¸·Î sort µÊ
--> Sort ÈÄ
2 3 4 5 6 7 8 100 1 : ¾²·¹µå ¹øÈ£
+-+-+-+-+-+-+-+---+-+-+
|0|0|0|0|0|0|0|...|0|1|
+-+-+-+-+-+-+-+---+-+-+
--> Ŭ¶óÀÌ¾ðÆ®°¡ 99°³°¡ Á¢¼ÓÇØ ÀÖÀ»°æ¿ì
+-+-+-+-+-+-+-+---+-+-+
|0|1|1|1|1|1|1|...|1|1|
+-+-+-+-+-+-+-+---+-+-+
±×·³À¸·Î begin() À» »ç¿ëÇÏ°Ô µÉ°æ¿ì
¾ðÁ¦³ª È޽ĻóÅ¿¡ ÀÖ´Â ¾²·¹µå¸¦ °¡Á®¿Ã¼ö ÀÖÀ½
|
»ç½Ç multimap À» ¾´´Ù¸é ±»ÀÌ "ÇöÀç ¿¬°áµÈ Ŭ¶óÀÌ¾ðÆ® ¼ö" ¸¦
À¯ÁöÇϱâ À§Çؼ º°µµÀÇ º¯¼ö¸¦ µÑ Çʿ䰡 ¾øÀ»°ÍÀÌ´Ù.
multimap ¿¡¼ Á¦°øÇÏ´Â count() ¸¦ ÀÌ¿ëÇØ¼ key °¡ "1" ÀÎ
¿ä¼ÒÀÇ ¼ö¸¦ ±¸ÇÏ¸é µÇ±â ¶§¹®ÀÌ´Ù. ¸¸¾à multimp ÀÇ begin()
°ªÀÌ 1 À̶ó¸é MAX Ŭ¶óÀÌ¾ðÆ®°¡ °¡µæÃ¡´Ù´Â°É ÀǹÌÇÒ°ÍÀÌ´Ù.
¹°·Ð multimap ÀÇ °æ¿ì ±âº»ÀûÀ¸·Î key °ªÀÇ ¼öÁ¤Àº Çã¿ëÇÏÁö ¾Ê±â
¶§¹®¿¡ 0 À» 1·Î º¯°æÇÒ°æ¿ì ½ÇÁ¦·Î´Â
0 À» °¡Áö´Â ¿ä¼Ò¸¦ »èÁ¦Çϰí, 1À» °¡Áö´Â »õ·Î¿î ¿ä¼Ò¸¦ »ðÀÔÇÏ´Â
¹æ½ÄÀ» ÃëÇØ¾ß ÇÒ°ÍÀÌ´Ù. ¸¶Âù°¡Áö·Î Ŭ¶óÀÌ¾ðÆ®°¡ Á¾·áÇØ¼
1À» 0À¸·Î º¯°æÇÒ¶§¿¡µµ »èÁ¦/ÀμƮ¸¦ ÇØ¾ßÇÒ°ÍÀÌ´Ù.
Value(°ª) ´Â ±×´ë·Î º¹»çÇØ¼ »èÁ¦/ÀμƮ¸¦ ÇØ¾ß ÇÑ´Ù.
ÀÌ ¹æ¹ýÀÌ ¹ø°Å·Ó´Ù¸é, ±×³É ¹è¿À» ¾²°Å³ª ȤÀº ´Ù¸¥ ¾î¶² ÀڷᱸÁ¶¸¦
¾²´õ¶óµµ ÀüÇô °ü°è¾ø±â´Â ÇÏ´Ù. ±×°Ç ÀÚ±âÀÇ ±âÈ£¿¡ ¸Â°Ô ¼±ÅÃÇØ¼
»ç¿ëÇÏ¸é µÉ¹®Á¦ÀÌ´Ù.
Áö±Ý±îÁö Thread POOL ÀÇ ±¸Çö¹æ¹ý¿¡ ´ëÇØ¼ ¾Ë¾ÆºÃÀ¸´Ï,
°£´ÜÇÏ°Ô ±¸ÇöÇØ º¸µµ·Ï ÇϰڴÙ. ÀÌ ÄÚµå´Â Áö±ØÈ÷ ±â´É±¸Çö¿¡¸¸
½Å°æ¾´ ÄÚµåÀÌ´Ù. ¿¡·¯Ã³¸®¿Í ¸î±ºµ¥ ¹ÂÅØ½ºÀá±Ý󸮴 °¢ÀÚÀÇ
Àç·®¿¡ ¸Ã±â°Ú´Ù.
¿¹Á¦ : pool_echo.cc
#include <map>
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// ÃÖ´ë ¾²·¹µå POOL Å©±â
#define MAX_THREAD_POOL 256
using namespace std;
// Àü¿ª ¾²·¹µå ±¸Á¶Ã¼
typedef struct _ph
{
int sockfd; // ÇöÀç »ç¿ëÁßÀÎ ¼ÒÄÏ fd
int index_num; // À妽º ¹øÈ£
} ph;
// Àü¿ª¾²·¹µå ±¸Á¶Ã¼·Î½á
// ÇöÀç ¾²·¹µå »óȲÀ» ÆÄ¾ÇÇÔ
struct schedul_info
{
int client_num; // ÇöÀç ¿¬°áµÈ Ŭ¶óÀÌ¾ðÆ®¼ö
int current_sockfd; // °¡ÀåÃÖ±Ù¿¡ ¸¸µé¾îÁø ¼ÒÄÏÁö½ÃÀÚ
multimap<int, ph> phinfo;
};
// °¢ ¾²·¹µåº° Á¶°Çº¯¼ö
pthread_cond_t *mycond;
// ¾²·¹µå µ¿±âȸ¦ À§ÇÑ Á¶°Çº¯¼ö
pthread_cond_t async_cond = PTHREAD_COND_INITIALIZER;
// °¢ ¾²·¹µåº° Á¶°Çº¯¼öÀÇ Å©¸®Æ¼Äü¼¼Ç ÁöÁ¤À» À§ÇÑ
// ¹ÂÅØ½º
pthread_mutex_t mutex_lock= PTHREAD_MUTEX_INITIALIZER;
// ¾²·¹µå µ¿±âÈ¿ë Á¶°Çº¯¼öÀÇ Å©¸®Æ¼Äü¼¼Ç ÁöÁ¤À» À§ÇÑ
// ¹ÂÅØ½º
pthread_mutex_t async_mutex = PTHREAD_MUTEX_INITIALIZER;
// Ŭ¶óÀÌ¾ðÆ®¿ÍÀÇ Åë½Å¿ë ¾²·¹µå
void *thread_func(void *data);
// ÇöÀç Ŭ¶óÀÌ¾ðÆ® »óÅ ¸ð´ÏÅÍ¿ë ¾²·¹µå
// ÇѸ¶µð·Î µð¹ö±ë¿ë
void *mon_thread(void *data);
schedul_info s_info;
// ¸ÞÀÎ ÇÔ¼ö
int main(int argc, char **argv)
{
int i;
ph myph;
int status;
int pool_size = atoi(argv[2]);
pthread_t p_thread;
struct sockaddr_in clientaddr, serveraddr;
int server_sockfd;
int client_sockfd;
int client_len;
// Ç®»çÀÌÁî °Ë»ç
if ((pool_size < 0) || (pool_size > MAX_THREAD_POOL))
{
cout << "Pool size Error" << endl;
exit(0);
}
// Make Socket
if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("error : ");
exit(0);
}
// Bind
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(atoi(argv[1]));
if (bind (server_sockfd, (struct sockaddr *)&serveraddr,
sizeof(serveraddr)) == -1)
{
perror("bind error : ");
exit(0);
}
// Listen
if (listen(server_sockfd, 5) == -1)
{
perror("listen error : ");
exit(0);
}
// ¾²·¹µå °¹¼ö¸¸Å Á¶°Çº¯¼ö »ý¼º
mycond = (pthread_cond_t *)malloc(sizeof(pthread_cond_t)*pool_size);
// ¾²·¹µå Àü¿ªº¯¼ö ÃʱâÈ
s_info.client_num = 0;
s_info.current_sockfd = 0;
// ¾²·¹µå POOL »õ¼º
for (i = 0; i < pool_size; i++)
{
memset((void *)&myph, 0x00, sizeof(myph));
myph.index_num = i;
s_info.phinfo.insert(pair<int, ph>(0, myph));
// Á¶°Çº¯¼ö¸¦ ÀÌ¿ëÇØ¼ ¾²·¹µå°£ µ¿±âȸ¦ ½Ç½ÃÇÑ´Ù.
pthread_mutex_lock(&async_mutex);
if (pthread_create(&p_thread, NULL, thread_func, (void *)&i) < 0)
{
perror("thread Create error : ");
exit(0);
}
pthread_cond_wait(&async_cond, &async_mutex);
pthread_mutex_unlock(&async_mutex);
}
// µð¹ö±ë¿ë ¾²·¹µå »ý¼º
pthread_create(&p_thread, NULL, mon_thread, (void *)NULL);
// MAIN THREAD accept wait
client_len = sizeof(clientaddr);
// Ŭ¶óÀÌ¾ðÆ® ACCEPT 󸮸¦ À§ÇÑ
// MAIN ¾²·¹µå
while(1)
{
multimap<int, ph>::iterator mi;
client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr,
(socklen_t *)&client_len);
if (client_sockfd > 0)
{
// ¸¸¾à ¾²·¹µåÇ®ÀÌ °¡µæÃ¡´Ù¸é Ŭ¶óÀÌ¾ðÆ® ¿¬°áÀ»
// Á¾·á½ÃŲ´Ù.
mi = s_info.phinfo.begin();
if (mi->first == 1)
{
//error message send to client_sockfd
cout << "SOCKET IS FULL" << endl;
close(client_sockfd);
}
// ±×·¸Áö ¾Ê´Ù¸é ¿¬°áÀ» ¹Þ¾ÆµéÀ̰í
// Ŭ¶óÀÌ¾ðÆ® Àü¿ª º¯¼ö¸¦ ¼¼ÆÃÇÑ´Ù.
// ¼¼ÆÃÈÄ ÇØ´ç 󸮾²·¹µå¿¡°Ô ½Ã±×³ÎÀ» º¸³»¾î¼
// ó¸®ÇÏ°Ô ÇÑ´Ù.
else
{
ph tmpph;
int psockfd;
int pindex_num;
s_info.current_sockfd = client_sockfd;
tmpph.sockfd = client_sockfd;
tmpph.index_num = mi->second.index_num;
s_info.phinfo.erase(mi);
s_info.phinfo.insert(pair<int, ph>(1,tmpph));
s_info.client_num ++;
cout << "SEND SIGNAL " << mi->second.index_num << endl;
pthread_cond_signal(&mycond[mi->second.index_num]);
}
}
else
{
cout << "ACCEPT ERROR " << endl;
}
}
pthread_join(p_thread, (void **)status);
}
void *thread_func(void *data)
{
char buf[255];
int mysocket;
int mynum = *((int *)data);
multimap<int, ph>::iterator mi;
// ¾²·¹µå µ¿±âÈ¿ë Á¶°Çº¯¼ö
pthread_mutex_lock(&async_mutex);
pthread_cond_signal(&async_cond);
pthread_mutex_unlock(&async_mutex);
cout << "Thread create " << mynum << endl;
while(1)
{
// MAIN ¾²·¹µå·Î ºÎÅÍ ½ÅÈ£¸¦ ±â´Ù¸°´Ù.
// ½ÅÈ£°¡ µµÂøÇÏ¸é ¾²·¹µå Àü¿ªº¯¼ö·Î ºÎÅÍ
// ÇöÀç ó¸®ÇؾßÇÒ ¼ÒÄÏÁöÁ¤°ªÀ» °¡Á®¿Â´Ù.
pthread_mutex_lock(&mutex_lock);
pthread_cond_wait(&mycond[mynum], &mutex_lock);
mysocket = s_info.current_sockfd;
pthread_mutex_unlock(&mutex_lock);
memset(buf, 0x00, 255);
// µ¥ÀÌŸ¸¦ ó¸®ÇÑ´Ù.
// ¸¸¾à quit ¹®ÀÚ¿À» ¸¸³ª¸é
// ¾²·¹µå Àü¿ªº¯¼ö¸¦ ¼¼ÆÃÇÑ´ÙÀ½ ¿¬°áÁ¾·á ÇÑ´Ù.
while(1)
{
read(mysocket, buf, 255);
if (strstr(buf, "quit") == NULL)
{
write(mysocket, buf, 255);
}
else
{
mi = s_info.phinfo.begin();
while(mi != s_info.phinfo.end())
{
cout << "search " << mi->second.index_num << endl;
if (mi->second.index_num == mynum)
{
ph tmpph;
tmpph.index_num = mynum;
tmpph.sockfd = 0;
s_info.phinfo.erase(mi);
s_info.phinfo.insert(pair<int, ph>(0, tmpph));
s_info.client_num --;
close(mysocket);
break;
}
mi ++;
}
break;
}
memset(buf, 0x00, 255);
}
}
}
void *mon_thread(void *data)
{
cout << "moniter thread" << endl;
while(1)
{
sleep(10);
multimap<int, ph>::iterator mi;
mi = s_info.phinfo.begin();
cout << "size " << s_info.phinfo.size() << endl;
while(mi != s_info.phinfo.end())
{
cout << mi->first << " : " << mi->second.index_num
<< " : " << mi->second.sockfd << endl;
mi ++;
}
}
}
|
ÀÌ ÇÁ·Î±×·¥Àº 2°³ÀÇ ÀÎÀÚ¸¦ ¹Þ¾ÆµéÀ̸ç, Ŭ¶óÀ̾ðÆ®ÀÇ
ÀÔ·ÂÀ» µÇµ¹·ÁÁÖ´Â ÀÏÀ»ÇÑ´Ù (echo ¼¹ö).
ù¹øÂ° ÀÎÀÚ´Â ¼ºñ½ºÇÒ PORT ¹øÈ£À̰í, µÎ¹øÂ° ÀÎÀÚ´Â
¾²·¹µå »ý¼º°¹¼öÀÌ´Ù. ÇÁ·Î±×·¥Àº ÀÎÀÚÀÇ Á¤º¸¸¦ ÀÌ¿ëÇØ¼
PORT ¸¦ ¿°í Ŭ¶óÀÌ¾ðÆ®¸¦ ¹Þ¾ÆµéÀδÙ. Ŭ¶óÀÌ¾ðÆ®°¡ ¿¬°áÇϸé,
Thread Pool ¿¡ ³²´Â °ø°£ÀÌ ÀÖ´ÂÁö¸¦ È®ÀÎÇϰí, ³²´Â °ø°£ÀÌ
ÀÖ´Ù¸é Ŭ¶óÀÌ¾ðÆ®¿Í Åë½ÅÇÏ°Ô µÈ´Ù.
´ÜÁö ¾²·¹µå¸¦ ¹Ì¸® »ý¼º½ÃŰ°í ³ª¼, À̰ÍÀ» ½ºÄÉÁ층Çϱâ À§ÇÑ
Äڵ尡 ¸îÁÙ Ãß°¡µÇ¾úÀ» »Ó
Ưº°È÷ º¹ÀâÇÑ ÄÚµå´Â ¾Æ´Ò°Å¶ó°í »ý°¢µÈ´Ù.
ÀÌ»ó °£´ÜÇÑ ¾²·¹µå Ç®ÀÇ ÀÛ¼º¿ä·É¿¡ ´ëÇØ¼ ¾Ë¾Æº¸¾Ò´Ù.
À§¿¡¼ ¼³¸íÇßµíÀÌ ¾²·¹µå Ç®À̶õ °³³äÀûÀÎ ¿ä¼Ò¿¡ °¡±î¿òÀ¸·Î
¾î¶»°Ô ±¸ÇöÇÒÁö´Â »óȲ¿¡ µû¶ó¼ ¸Å¿ì ´Þ¶óÁö°Ô µÇ¸ç,
À§ÀÇ ¿¹Á¦´Â ±×·¯ÇÑ ¿©·¯°¡Áö »óȲÁß °¡Àå ±âº»ÀûÀÎ »óȲÀ»
¿¹·Î ÇØ¼ ¸¸µé¾îÁø °ÍÀÌ´Ù. ¾î¶µç À§ÀÇ ¿¹Á¦¸¦ ÃæºÐÈ÷ ÀÌÇØÇÑ´Ù¸é
´Ù¸¥ »óȲÀ¸·ÎÀÇ ÀÀ¿ë¿ª½Ã º° ¾î·Á¿ò¾øÀ» °ÍÀ̶ó°í »ý°¢µÈ´Ù.
¾²·¹µå Ç®Àº º¸Åë ¸Å¿ì È¿À²ÀûÀÎ ¼º´ÉÀ» º¸ÀåÇØÁÖ´Â ¾îÇø®ÄÉÀ̼ÇÀÇ
ÀÛ¼ºÀ» À§Çؼ »ç¿ëµÇ¾îÁüÀ¸·Î, °¡´ÉÇÑÇÑ ºü¸¥ ¾²·¹µå°£ ÀüȯÀÌ °¡´ÉÇϵµ·Ï
°í¹ÎÇØ¼ ÄÚµùÀ» ÇØ¾ß ÇÑ´Ù. À§ÀÇ °æ¿ì ¾²·¹µå°£ ÀüȯÀ» À§Çؼ
multimap À» »ç¿ëÇϰí Àִµ¥, accept °¡ µé¾î¿ÔÀ»°æ¿ì ÇØ´ç Ŭ¶óÀÌ¾ðÆ®¿¡ ´ëÇÑ
¾²·¹µå ÇÒ´çÀº ¸Å¿ì ºü¸£´Ù°í º¼¼ö ÀÖÀ»°ÍÀÌ´Ù. ±×·¯³ª
Á¾·áÇÒ°æ¿ì¿¡´Â multimap ÀÇ Ã¹¹øÂ° ¿ø¼ÒºÎÅÍ ¸¶Áö¸·¹ø ¿ø¼Ò±îÁö
search ÇØ¾ß ÇÑ´Ù. À̰ÍÀº ¸Å¿ì ºñÈ¿À²ÀûÀÓÀ¸·Î °³¼±ÇÒ ¿©Áö°¡ ÀÖ´Ù.
°¡Àå °£´ÜÇÏ°Ô »ý°¢ÇÒ¼ö ÀÖ´Â °ÍÀº multimap ÀÇ key °ªÀÌ 1ÀÎ ¿ø¼Ò³»¿¡¼¸¸
°Ë»öÇÏ´Â °ÍÀÌ´Ù. ¿ì¸®´Â ¾²·¹µå Ç®ÀÇ Å©±â¿Í ÇöÀç ¿¬°áµÈ
Ŭ¶óÀ̾ðÆ®ÀÇ ¼ö¸¦ ¾Ë°í ÀÖÀ½À¸·Î, multimap ÀÇ ¸î¹øÂ° ¿ä¼ÒºÎÅÍ key °ªÀÌ
1ÀÎÁö¸¦ °è»êÇØ ³¾¼ö Àֱ⠶§¹®ÀÌ´Ù. ÀÌ·¸°Ô ÇÒ°æ¿ì ¾à°£ÀÇ ½Ã°£´ÜÃàÈ¿°ú¸¦
±â´ëÇÒ¼ö ÀÖÀ»°ÍÀÌ´Ù.
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0|0|0|0|0|0|0|0|1|1|1|1|1|1|1|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+-------------+
15 - 8
|
ÀÌ ½Ã°£´ÜÃàÈ¿°ú´Â ¿¬°áµÈ Ŭ¶óÀ̾ðÆ®ÀÇ ¼ö°¡ Àüü POOL »çÀÌÁî¿¡ ºñ·ÊÇØ¼
ÀÛÀ» ¼ö·Ï Ä¿Áú°ÍÀÌ´Ù.
³ª¸ÓÁö ¹æ¹ýÀº °¢ÀÚ °í¹ÎÀ» ÇØº¸±â ¹Ù¶õ´Ù. ¾Æ¸¶ ÀüÇô ´Ù¸¥ ÀڷᱸÁ¶¸¦
»ç¿ëÇÒ¼öµµ ÀÖÀ»°ÍÀÌ´Ù.
|
|
|
|