¾²·¹µå °´Ã¼ÀÇ »ç¿ë
ÃÑ ÆäÀÌÁö ¼ö : 3224

Àüü ÇÔ¼ö/¿ë¾î»çÀü
Facebook Joinc ±×·ì   Joinc QA »çÀÌÆ®



joinc´Â Firefox¿Í chrome¿¡¼­ Å×½ºÆ® Çß½À´Ï´Ù. IE¿¡¼­´Â Å×À̺íÀÌ ±úÁö°Å³ª À̹ÌÁö°¡ º¸ÀÌÁö ¾ÊÀ» ¼ö ÀÖ½À´Ï´Ù. ƯÈ÷ ±¸±Û DocsÀ̹ÌÁöÀÇ °æ¿ì ¿¢¹Úó¸®µÉ ¼ö ÀÖ½À´Ï´Ù.

Contents

1 ¸ñ Àû
1.1 Code 1
1.2 Code 2
1.3 ¹ÌºñÁ¡
1.4 Àâ ´ã
2 ¾²·¹µå °´Ã¼ÀÇ ÀÚ¿ø Á¤¸®
2.1 Å×½ºÆ® ¼­¹ö ÇÁ·Î±×·¥

1 ¸ñ Àû

  • C++ ¿¡¼­ ÀÚ¹ÙÀÇ ±×°Í°ú ºñ½ÁÇÑ thread °´Ã¼¸¦ ¸¸µé¾î »ç¿ëÇÑ´Ù
  • °´Ã¼ÁöÇâ°³³ä¿¡¼­ °¢ ¾²·¹µå¶õ°Ç ÇÁ·Î±×·¥¿¡¼­ °¡Àå Å« °´Ã¼µ¢¾î¸®·Î º¼ ¼ö ÀÖÀ¸¸ç, ±×·± °üÁ¡¿¡¼­ ÇϳªÀÇ Å¬·¡½ºÀÇ ÀνºÅϽº ÀÚü·Î ¾²·¹µå°¡ µÈ´Ù¸é °³³äÀûÀ¸·Î ÁÁÀ»°ÍÀÌ´Ù
  • Ŭ·¡½ºÀÇ ÀνºÅϽº¸¦ »ý¼ºÇϴ¼ø°£ Ŭ·¡½ºÀÇ ¸â¹öº¯¼ö¿Í ¸Þ¼Òµå¸¦ °¡Áö°í Ȱµ¿ÇÏ´Â ¾²·¹µå°¡ °¡µ¿µÈ´Ù
  • µ¡ºÙ¿©, µ¥¸ó ÇÁ·Î±×·¥¿¡¼­ stop, restart ½Ã¿¡ º¸Åë ¹ß»ý½ÃŰ´Â SIGTERM ½ÅÈ£¸¦ ¹Þ¾Æ¼­ °¢ ÀÚ½Ä ¾²·¹µåµéÀ» Á¾·á½ÃŲ ÈÄ ¾²·¹µå °´Ã¼ÀÇ ¼Ò¸êÀÚ¸¦ È£ÃâµÇ°Ô ÇÏ¿© µ¿ÀûÀ¸·Î »ý¼ºÇÑ ¸Þ¸ð¸® ¹× °¢Á¾ Á¤¸®ÇؾßÇÒ Çڵ鷯µéÀ» ÇØÁ¦½ÃŲ´Ù

1.1 Code 1

/* ÀÚ¹ÙÀÇ ±×°Í°ú ºñ½ÁÇÑ ¾²·¹µå °´Ã¼ Ŭ·¡½º ¶Ç´Â ÀÎÅÍÆäÀ̽º ±¸Çö */ 
/* µ¥¸óÀ¸·Î ½ÇÇà½Ã stop ¿¡ ÀÇÇÑ SIGTERM ½ÅÈ£¿¡ ¾²·¹µå°´Ã¼ÀÇ ¼Ò¸êÀÚ È£Ãâó¸® */ 
                                                                                                                              
#include <pthread.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <iostream> 
                                                                                                                              
using namespace std; 
                                                                                                                              
class tClass { 
                                                                                                                              
   private : 
      pthread_t pt; 
      int* a; 
      void prn(void) { 
         cout << "This is private method " << *a << endl; 
      } 
      // ¾Æ·¡´Â ¾²·¹µå¿¡¼­ ½ÇÁ¦ »ç¿ëµÉ ¸ÞÀÎ ÇÔ¼öÀÌ´Ù. ¼ø¼ö°¡»óÇÔ¼ö·Î Á¤ÀÇÇÏ¿© ÀÌ Å¬·¡½º¸¦ 
      // ÀÎÅÍÆäÀ̽ºÈ­ÇÏ¿© »ó¼Ó¹Þ´Â Ŭ·¡½º¿¡¼­ ¾²·¹µåÇÔ¼ö·Î ÇÊ¿äÇÑ ÀÛ¾÷À» Á¤ÀÇÇÏ¿© »ç¿ëÇÒ 
      // ¼ö µµ ÀÖ°Ú´Ù. ±×·²¶© protected ȤÀº public ¸â¹ö·Î ¸¸µé¾î³õ¾Æ¾ß »ó¼Ó¹Þ´Â Ŭ·¡½º¿¡¼­ 
      // ÀÌ ¼ø¼ö°¡»óÇÔ¼öÀÇ ³»¿ëÀ» Á¤ÀÇÇÏ¿© »ç¿ëÇÒ ¼ö°¡ ÀÖ°Ú´Ù. ¶ÇÇÑ pthread_create¸¦ »ý¼ºÀÚ¿¡¼­ 
      // È£ÃâÇÏ¸é »ó¼Ó¹ÞÀº Ŭ·¡½º¿¡¼­ ³»¿ëÀ» Á¤ÀÇÇØ³õÀº tFunc °¡ È£ÃâµÉ ¼ö ¾øÀ¸¹Ç·Î »ý¼ºÀÚ¿¡¼± 
      // pthread_create¸¦ ÇÏÁö ¾Ê°í µû·Î ¸â¹öÇÔ¼ö¸¦ µÎ¾î °Å±â¼­ ¾²·¹µåÈ£ÃâÀ» ÇØ¾ßÇÑ´Ù. 
      void tFunc(void) { 
         *a = 1; 
         prn(); 
         while (1) { 
            cout << "This is thread method " <<  (*a)++ << endl; 
            sleep(1); 
         } 
      } 
      static void* callThread(void* arg); // ½ÇÁ¦ pthread_create¿¡ »ç¿ëµÇ´Â ¸Þ¼Òµå 
 
   public : 
      tClass(void) { 
         cout << "This is constructor" << endl; 
         a = new int; 
         pthread_create(&pt, NULL, callThread, this); 
         // static ¸â¹ö¸Þ¼Òµå´Â static¸â¹ö¿¡¸¸ Á¢±Ù°¡´ÉÇϹǷΠÀÌ Å¬·¡½ºÀÇ °´Ã¼ÁÖ¼Ò¸¦ 
         // ÀÎÀÚ·Î ³Ñ°Ü private¸¦ Æ÷ÇÔÇÑ ¸ðµç ¸â¹ö¸¦ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ÇÑ´Ù. 
      } 
      ~tClass(void) { 
         int i; 
         // mainÀÇ Á¾·á½Ã Á¾¼Ó¾²·¹µå¸¦ ¸ÕÀú Á¾·á½ÃŰ´ÂÁö ÀνºÅϽºµéÀÇ ¸Þ¸ð¸®ÇØÁ¦¸¦ 
         // ¸ÕÀú ½ÃŰ´ÂÁö ¾Ë¾Æº¸±â À§ÇÏ¿© ·çÇÁ¸¦ µ¹¸² 
         for (i = 0; i < 3; i++) { 
            cout << "This is destructor" << endl; 
            sleep(1); 
         } 
         delete a; 
      } 
                                                                                                                              
}; 
                                                                                                                              
// static ¸â¹öº¯¼ö´Â Ŭ·¡½º ¼±¾ð ¹Û¿¡¼­ Á¤ÀÇÇØ¾ßÇÔ 
void* tClass :: callThread(void* arg) { 
   tClass* tp; 
   tp = (tClass*) arg; 
   tp->tFunc();   // ¾²·¹µåÀÛ¾÷À» ÇÒ ¸Þ¼Òµå¸¦ ½ÇÇà½ÃŲ´Ù 
   // ÀÌ °÷¿¡¼­ Á÷Á¢ ¾²·¹µåÀÛ¾÷µéÀ» ÇÏ¿©µµ µÇ°ÚÀ¸³ª, Ŭ·¡½º¸â¹ö¸¦ »ç¿ëÇÒ¶§¸¶´Ù 
   // Æ÷ÀÎÅ͸¦ ÅëÇØ Á¢±ÙÇØ¾ß ÇϹǷΠ±ò²ûÇÏÁö ¸øÇϸç ÀÌ Å¬·¡½º¸¦ ÀÎÅÍÆäÀ̽ºÈ­ÇÏÁö ¸øÇÑ´Ù 
} 
                                                                                                                              
int main () { 
   int i; 
   tClass tc; 
   for (i = 0; i <  3; i++) { 
      cout << "This is main" << endl; 
      sleep(1); 
   } 
   cout << "main exit" << endl; 
   return (1); 
} 
 
  • ½ÇÇàÀ» ½ÃÄѺ¸¸é main Á¾·á½Ã¿¡ °´Ã¼(º¯¼ö¸¦ Æ÷ÇÔÇÑ ¸ðµç ÀνºÅϽºµé)ÀÇ ÇØÁ¦°¡ ¸ÕÀú ÀϾ°í - ¼Ò¸êÀÚ°¡ ½ÇÇàµÇ´Â µ¿¾È °´Ã¼ ¾²·¹µå°¡ °è¼Ó ½ÇÇàµÇ°í ÀÖÀ½ - ±× ´ÙÀ½ °¢ ¾²·¹µåÀ» Á¾·áÇϰí mainÀÌ Á¾·áµÇ´Â°ÍÀ» ¾Ë ¼ö ÀÖ´Ù. À̰ÍÀº º¸Åë ¾Æ¹« ¹®Á¦µµ µÇÁö ¾Ê´Â´Ù. ¼Ò¸êÀÚ°¡ ½ÇÇàµÇ°í ¾²·¹µå°¡ Á¾·áµÇ´Â°Ç ¾ÆÁÖ ºü¸¥ ¼ø°£¿¡ ÀϾ°ÍÀÌ´Ù. ±×·¯³ª, ÀÌ¹Ì ÇØÁ¦µÈ ¸Þ¸ð¸®³ª Çڵ鷯¿¡ ¾î¶² ¿¢¼¼½º°¡ °¡ÇØÁú È®·üÀÌ Á¸ÀçÇѴٴ°ÍÀº °áÄÚ ±ò²ûÇÏÁö ¸øÇÏ´Ù(Àû¾îµµ ³ª´Â ÂóÂóÇÏ´Ù). ±×¸®ÇÏ¿©, º¸Åë µ¥¸óÀÇ stop ½ºÅ©¸³Æ®¿¡¼­ ¹ß»ý½ÃŰ´Â SIGTERMÀ» ó¸®ÇÏ´Â Çڵ鷯¸¦ µÎ¾î ¼öµ¿À¸·Î ¸ÕÀú ¾²·¹µå¸¦ Á¾·á½ÃŲ ÈÄ ¼Ò¸êÀÚ°¡ È£ÃâµÇ°Ô ÇØº¸ÀÚ.

1.2 Code 2

/* ÀÚ¹ÙÀÇ ±×°Í°ú ºñ½ÁÇÑ ¾²·¹µå °´Ã¼ Ŭ·¡½º ¶Ç´Â ÀÎÅÍÆäÀ̽º ±¸Çö */
/* µ¥¸óÀ¸·Î ½ÇÇà½Ã stop ¿¡ ÀÇÇÑ SIGTERM ½ÅÈ£¿¡ ¾²·¹µå°´Ã¼ÀÇ ¼Ò¸êÀÚ È£Ãâó¸® */

#include <signal.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>

using namespace std;

class tClass {

   private :
      int* a;
      void prn(void) {
         cout << "This is private method " << *a << endl;
      }
      // ¾²·¹µåÇÔ¼öÀÌ´Ù. ¼ø¼ö°¡»óÇÔ¼ö·Î Á¤ÀÇÇÏ¿© ÀÌ Å¬·¡½º¸¦ ÀÎÅÍÆäÀ̽ºÈ­ÇÏ¿©
      // »ó¼Ó¹Þ´Â Ŭ·¡½º¿¡¼­ ¾²·¹µåÇÔ¼ö·Î ÇÊ¿äÇÑ ÀÛ¾÷À» Á¤ÀÇÇÏ¿© »ç¿ëÇÒ ¼ö µµ ÀÖ°Ú´Ù.
      void tFunc(void) {
         *a = 1;
         prn();
         while (1) {
            cout << "This is thread method " <<  (*a)++ << endl;
            sleep(1);
         }
      }
      static void* callThread(void* arg); // ½ÇÁ¦ pthread_create¿¡ »ç¿ëµÇ´Â ¸Þ¼Òµå

   public :
      pthread_t pt;  // main ¿¡¼­ÀÇ pthread_cacel È£ÃâÀ» À§ÇØ publicÀ¸·Î ÇÔ
      tClass(void) {
         cout << "This is constructor" << endl;
         a = new int;
         pthread_create(&pt, NULL, callThread, this);
         // static ¸â¹ö¸Þ¼Òµå´Â static¸â¹ö¿¡¸¸ Á¢±Ù°¡´ÉÇϹǷΠÀÌ Å¬·¡½ºÀÇ °´Ã¼ÁÖ¼Ò¸¦
         // ÀÎÀÚ·Î ³Ñ°Ü private¸¦ Æ÷ÇÔÇÑ ¸ðµç ¸â¹ö¸¦ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ÇÑ´Ù.
      }
      ~tClass(void) {
         int i;
         // mainÀÇ Á¾·á½Ã Á¾¼Ó¾²·¹µå¸¦ ¸ÕÀú Á¾·á½ÃŰ´ÂÁö ÀνºÅϽºµéÀÇ ¸Þ¸ð¸®ÇØÁ¦¸¦
         // ¸ÕÀú ½ÃŰ´ÂÁö ¾Ë¾Æº¸±â À§ÇÏ¿© ·çÇÁ¸¦ µ¹¸²
         for (i = 0; i < 3; i++) {
            cout << "This is destructor" << endl;
            sleep(1);
         }
         delete a;
      }

};

// static ¸â¹ö ¸Þ¼Òµå´Â Ŭ·¡½º ¼±¾ð ¹Û¿¡¼­ Á¤ÀÇÇØ¾ßÇÔ
void* tClass :: callThread(void* arg) {
   tClass* tp;
   pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
   pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
   tp = (tClass*) arg;
   tp->tFunc();   // ¾²·¹µåÀÛ¾÷À» ÇÒ ¸Þ¼Òµå¸¦ ½ÇÇà½ÃŲ´Ù
   // ÀÌ °÷¿¡¼­ Á÷Á¢ ¾²·¹µåÀÛ¾÷µéÀ» ÇÏ¿©µµ µÇ°ÚÀ¸³ª, Ŭ·¡½º¸â¹ö¸¦ »ç¿ëÇÒ¶§¸¶´Ù
   // Æ÷ÀÎÅ͸¦ ÅëÇØ Á¢±ÙÇØ¾ß ÇϹǷΠ±ò²ûÇÏÁö ¸øÇϸç ÀÌ Å¬·¡½º¸¦ ÀÎÅÍÆäÀ̽ºÈ­ÇÏÁö ¸øÇÑ´Ù
}

tClass tc;  // sigHandler¿¡¼­ÀÇ ÀÛ¾÷À» À§ÇØ Àü¿ªÀ¸·Î ¼±¾ð

void sigHandler(int sig) {
   cout << "Got signal " << sig << endl;
   pthread_cancel(tc.pt);        // ¾²·¹µå Á¾·á
   pthread_join(tc.pt, NULL);
   cout << "Signal Handler exit" << endl;
   exit(EXIT_SUCCESS);
   // °´Ã¼ÀÇ ¼Ò¸êÀÚ´Â mainÀÌ Á¾·áµÇ¸é¼­ ÀÚµ¿À¸·Î È£ÃâµÈ´Ù. À̰͵µ Á÷Á¢ È£ÃâÇÒ·Á¸é
   // tClass* tc·Î ¼±¾ðÇÏ¿© newÇÏ¿© »ç¿ëÇÑ ÈÄ ¿©±â¼­ delete ÇÏ¸é µÈ´Ù
}

int main () {
   signal(SIGTERM, sigHandler);
   while (1) {
      cout << "This is main" << endl;
      sleep(1);
   }
}
  • ps ÇÏ¿© ³ª¿À´Â ÇÁ·Î¼¼½ºÁß¿¡ ÀÌ ÇÁ·Î±×·¥¸íÀÇ ÃÖ»óÀ§ pid¸¦ kill ÇØº¸ÀÚ (kill pid ȤÀº kill -TERM pid)
  • ÀÚ½Ä ¾²·¹µå¸¦ ¸ÕÀú Á¾·á½ÃŲ ÈÄ ¼Ò¸êÀÚ°¡ È£ÃâµÇ´Â°ÍÀ» ¾Ë ¼ö ÀÖ´Ù

1.3 ¹ÌºñÁ¡

  • ½Åȣ󸮱⿡¼­ ¾²·¹µå°´Ã¼¿¡ Á¢±ÙÇϱâ À§ÇÏ¿© ¾²·¹µå°´Ã¼ÀÇ ÀνºÅϽº¸¦ Àü¿ªÀ¸·Î ¼±¾ðÇÏ¿´´Ù. ÀÌ·¯ÇѰÍÀº °´Ã¼ÁöÇâ°³³ä¿¡¼­´Â ÁÁÁö ¸øÇÏ´Ù. °¡´ÉÇÑÇÑ Àü¿ªº¯¼ö´Â ¾²Áö ¾Ê´Â°ÍÀÌ ÁÁ´Ù. Ç㳪 ÀüÅëÀûÀÎ ½Ã±×³ÎÀº µ¥ÀÌÅ͸¦ Àü´ÞÇÒ ¼ö °¡ ¾ø´Ù. ¶§¹®¿¡ RTS ¸¦ »ç¿ëÇÏ¿© À̸¦ ÇØ°áÇÒ ¼ö ÀÖÀ»°ÍÀÌ´Ù. ȤÀº, µ¥¸óÁ¾·á½ÃÀÇ ¸Þ¸ð¸®¿Í ¾²·¹µå Á¤¸®¸¦ À§ÇÑ ´õ ÁÁÀº ¹æ¹ýÀÌ ÀÖÀ¸¸é ¾Ë·Á´Þ¶ó (Á¤¸®¾ÈÇØµµ µÈ´Ù´Â ¸»Àº ÇÏÁö¸»¾Æ´Þ¶ó. ³ªµµ ¾È´Ù. -.-; ±×·¯³ª ÇÏ´Â°Ô ÁÁÁö ¾Ê°Ú´Â°¡?)
  • ºÎ¸ð ¾²·¹µåÀÇ ºñµ¿±âÀûÀÎ Á¾·á½Ã, ÀÚ½Ä ¾²·¹µåÀÇ Ã³¸®´Â pthread_cancel()ÇÔ¼ö¸¦ ÀÌ¿ëÇϸé ÇØ°á°¡´ÉÇÒ °Å °°½À´Ï´Ù. ¹Ø¿¡ 2ÀåÀ» Çѹø Âü°íÇØ º¸½Ã±æ

1.4 Àâ ´ã

  • ¾îÁ¦, ¿À´Ã À§Å°¸¦ ÀÛ¼ºÇغ¸¾Ò´Ù. ¹«Áö Èûµé´Ù -.-; ½Ã°£ ¹«Áö Àâ¾Æ¸Ô´Â´Ù. È¥ÀÚ Å×½ºÆ®ÇÒ ¼Ò½º´Â ´ëÃæ Çϴµ¥ ¿©±â ¿Ã¸±·Á´Ï ÁÖ¼®µµ ´Þ°í º¯¼ö¸íµµ Á» ´Ùµë°í ÇÏ´ÂÀÏÀÌ ÈξÀ ¸¹´Ù. ¼¼»ó¿¡¼­ 2¹øÂ°·Î ¹Ù»Û(¹Ùºü¾ßÇÏ´Â) ³»°¡ °è¼Ó ±ÛÀ» ¿Ã¸± ¼ö ÀÖÀ»·ÃÁö ¸ð¸£°Ú´Ù. ±×º¸´Ù ÀÌ ±ÛµéÀÌ ´©±º°¡¿¡°Ô µµ¿òÀÌ µÉ·ÃÁö - ¾Æ¸¶ µÉ°ÍÀÌ´Ù. µÈ´Ù°í ÇØ´Þ¶ó - Àǹ®ÀÌ´Ù.

  • ¸¹Àº µµ¿òÀÌ µÇ°í ÀÖ½À´Ï´Ù. À̱âÀûÀÎ ¾ê±â Áö¸¸. Èû³»¼¼¿ä. :) (jinoos)

2 ¾²·¹µå °´Ã¼ÀÇ ÀÚ¿ø Á¤¸®

¾²·¹µå¸¦ Ŭ·¡½º¸¦ ÀÌ¿ëÇØ¼­ °´Ã¼È­ ÇÒ°æ¿ì, ¾²·¹µå¸¦ detach »óÅ·Π½ÇÇà½ÃŰ´Â °æ¿ì°¡ ¸¹´Ù. ÀÌ °æ¿ì pthread_joinc()ÇÔ¼ö¸¦ ÀÌ¿ëÇÏÁö ¾Ê°Ô µÊÀ¸·Î, ºÎ¸ð ¾²·¹µå´Â Àڽľ²·¹µåÀÇ »óŸ¦ Á¤È®ÇÏ°Ô ¾Ë±â Èûµé°í, ¶§¹®¿¡ ÀÚ¿øÁ¤¸®¿¡ ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. ÀÚ½Ä ¾²·¹µå°¡ ÀÚ½ÅÀÇ Á¾·á½ÃÁ¡À» ¸íÈ®È÷ ¾Ë°í ÀÖ´Ù¸é, ¼Ò¸êÀÚ¸¦ ÀÌ¿ëÇØ¼­ ÇÊ¿äÇÑ ÇØÁ¦¸¦ ÇÒ ¼ö ÀÖ°ÚÁö¸¸, pthread_cancel()µî ºñµ¿±âÀûÀÎ ¹æ¹ýÀ¸·Î Á¾·á ½Ãų°æ¿ì ¹®Á¦°¡ µÉ ¼ö ÀÖ´Ù.

¿©·¯°¡Áö ¹æ¹ýÀÌ ÀÖ°ÚÀ¸³ª, ÇÊÀÚ´Â pthread_cleanup_push()¿Í pthread_cleanpu_pop() ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ ÀÌ ¹®Á¦¸¦ ÇØ°áÇß´Ù.

2.1 Å×½ºÆ® ¼­¹ö ÇÁ·Î±×·¥

°£´ÜÇÑ Å×½ºÆ® ¼­¹ö ÇÁ·Î±×·¥À» ¸¸µé¾î º¸µµ·Ï ÇϰڴÙ. ÀÌ ÇÁ·Î±×·¥Àº echo Ŭ¶óÀ̾ðÆ®ÀÇ thread ¹öÁ¯ÀÌ´Ù. ¿¬°áÀÌ µé¾î¿À¸é ºÎ¸ð¾²·¹µå´Â »õ·Î¿î Àڽľ²·¹µå¸¦ »ý¼ºÇÑ´Ù. ¶ÇÇÑ ºÎ¸ð¾²·¹µå´Â select()¸¦ ÀÌ¿ëÇÏ¿© Ç¥ÁØÀÔ·ÂÀ» ±â´Ù¸°´Ù. ÀÌ Ç¥ÁØÀÔ·ÂÀ» ÅëÇØ¼­ ƯÁ¤ Àڽľ²·¹µå Á¾·á³ª Àڽľ²·¹µå »óÅ Á¤º¸Á¦°øµî°ú °°Àº ÀÏÀ» ÇÏ°Ô µÈ´Ù.
                                    +--------------+ 
                           +------> | child Thread |----+ 
                           |        +--------------+    |   +------------------+ 
 +-------------+ accept()  |        +--------------+    |   | CleanUp Function | 
 | Main Thread |-----------+------> | child Thread |----+---| + delete this    |  
 +-------------+           |        +--------------+    |   +------------------+ 
       |                   |        +--------------+    |            | 
       |                   +------> | child Thread |----+            | 
       |                            +--------------+                 | 
       |   pthread_cancel()                                          | 
       | ------------------------->  pthread_cleanup_push()----->>---+ 
       | 
   ---------------------- STDIN 
   Thread Information 
 


#include <pthread.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <iostream> 
#include <signal.h> 
 
#include <sys/stat.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
 
#include <string.h> 
#include <map> 
 
using namespace std; 
 
#define MAXLEN  256 
 
map<int, pthread_t> Cinfo; 
class tClass { 
    private : 
        pthread_t pt; 
        int sockfd; 
        char *buf; 
 
        static void* callThread(void* arg); 
        // ¾²·¹µå Á¾·áÇÔ¼ö 
        // ÀÚ½ÅÀ» delete ÇÑ´Ù. 
        static void clean_up(void *arg) 
        { 
            delete (tClass *)arg; 
        } 
 
    public : 
        // Client¿Í Åë½ÅÀ» ´ã´çÇÏ´Â ÇÔ¼ö·Î ¾²·¹µå ÇÔ¼öÀÎ callThread¿¡¼­  
        // È£ÃâÇÑ´Ù. 
        void tFunc(void)  
        { 
            int readn; 
            buf = (char *)malloc(MAXLEN); 
 
            // ¾²·¹µå Á¾·áÇÔ¼öÀÎ clean_upÀ» È£ÃâÇÑ´Ù. 
            // ÀÎÀÚ·Î ¾²·¹µå ÀÚ½ÅÀÇ Æ÷ÀÎÅ͸¦ ³Ñ±ä´Ù. 
            pthread_cleanup_push(clean_up, (void *)this); 
            while (1)  
            { 
                memset(buf, 0x00, MAXLEN); 
                readn = read(sockfd, buf, MAXLEN); 
                if(readn <=0) 
                { 
                    perror("Socket Read Error:");     
                    break; 
                } 
                write(sockfd, buf, strlen(buf)); 
            } 
            pthread_exit((void *)NULL); 
            // ¾²·¹µå Á¾·áÇÔ¼ö¸¦ pop½ÃŲ´Ù. 
            pthread_cleanup_pop(0); 
        } 
 
        tClass(int sfd)  
        { 
            sockfd = sfd; 
            buf = NULL; 
            pt = 0; 
            pthread_attr_t attr; 
 
            // ¾²·¹µå¸¦ Detached »óÅ·Π¸¸µç´Ù. 
            pthread_attr_init(&attr); 
            pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 
            pthread_create(&pt, &attr, callThread, this); 
        } 
 
        // ¸¸µé¾îÁø ¾²·¹µå°´Ã¼ÀÇ pthread_id¸¦ ¸®ÅÏÇÑ´Ù.  
        pthread_t tClassId() 
        { 
            return pt; 
        } 
 
        // ¼Ò¸êÀÚ·Î 
        // ¾²·¹µå ÀÚ¿ø°ú Àü¿ª ÀڷᱸÁ¶¸¦ Á¤¸®ÇÑ´Ù. 
        ~tClass(void)  
        { 
            map<int, pthread_t>::iterator mi; 
            if(buf)  
                free(buf);     
            if (sockfd) 
            { 
                mi = Cinfo.find(sockfd); 
                if (mi!=Cinfo.end()) 
                { 
                    Cinfo.erase(mi); 
            } 
            close(sockfd); 
        } 
        printf("Thread Close\n"); 
    } 
}; 
 
 
void* tClass :: callThread(void* arg)  
{ 
   tClass* tp; 
   tp = (tClass*) arg; 
   tp->tFunc();    
} 
 
int main (int argc, char **argv)  
{ 
    pthread_t pthread; 
    struct sockaddr_in clientaddr, serveraddr, myaddr; 
    int maxfd = 0; 
    fd_set fd_w; 
    struct timeval timeout; 
 
    class tClass *ClientClass; 
 
    int server_sockfd, client_sockfd, client_len; 
 
    if (argc != 2) 
    { 
        printf("Usage : %s [PORT]\n", argv[0]);  
        return 1; 
    } 
 
    if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
    { 
        perror("socket error:"); 
        return 1; 
    } 
 
    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:"); 
        return 1; 
    } 
    if (listen(server_sockfd, 5) == -1) 
    { 
        perror("listen error :"); 
        return 1; 
    } 
    client_len = sizeof(clientaddr); 
 
    char buf[MAXLEN]; 
 
    // Main Thread 
    // Accept ÀÔ·ÂÀÎ °æ¿ì »õ·Î¿î ¾²·¹µå¸¦ »ý¼º½Ã۰í 
    // Ç¥ÁØÀÔ·ÂÀÎ °æ¿ì ÀÔ·ÂµÈ ¸í·ÉÀ» È®ÀÎÇØ¼­    
    // showÀϰæ¿ì ¾²·¹µå Á¤º¸¸¦ º¸¿©ÁÖ°í 
    // killÀÏ °æ¿ì ÇØ´ç ¾²·¹µå¸¦ Á¾·á½ÃŲ´Ù.  
    // kill Àº ÇϳªÀÇ ÀÎÀÚ¸¦ °¡Áø´Ù. ÀÎÀÚ´Â ¼ÒÄÏÁöÁ¤¹øÈ£´Ù. 
    while(1) 
    { 
        FD_ZERO(&fd_w); 
        FD_SET(0,  &fd_w); 
        FD_SET(server_sockfd, &fd_w); 
 
        select(server_sockfd + 1, &fd_w, (fd_set *)0, (fd_set*)0, NULL);  
        if(FD_ISSET(server_sockfd,&fd_w)) 
        { 
            client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr, 
                                            (socklen_t *)&client_len); 
            ClientClass = new tClass(client_sockfd); 
            Cinfo[client_sockfd] = ClientClass->tClassId(); 
        } 
        else if(FD_ISSET(0, &fd_w)) 
        { 
            memset(buf, 0x00, MAXLEN); 
            read(0, buf, MAXLEN); 
            if(strncmp(buf, "show", 4) == 0) 
            { 
                map<int, pthread_t>::iterator mi; 
                mi = Cinfo.begin(); 
                printf("NUM\tThread ID\tClient Address\n"); 
                while(mi != Cinfo.end()) 
                { 
                    getsockname(mi->first, (struct sockaddr *)&myaddr, (socklen_t *)&client_len); 
                    printf("%d\t%u\t%s\n", mi->first, mi->second, inet_ntoa(myaddr.sin_addr)); 
                    *mi++; 
                } 
                printf("=============================\n"); 
            } 
            if (strncmp(buf, "kill", 4) == 0) 
            { 
                map<int, pthread_t>::iterator mi; 
                mi = Cinfo.find(atoi(buf+5)); 
                if (mi == Cinfo.end()) 
                { 
                    printf("Not Found Thread\n"); 
                } 
                else 
                { 
                    printf("Kill Thread %u\n", mi->second); 
                    pthread_cancel(mi->second); 
                } 
            } 
        } 
        else 
        { 
            printf("Unknown\n"); 
        } 
    } 
 
} 
 
´ÙÀ½Àº Å×½ºÆ® °á°ú´Ù.
# ./thclass 2222 
show 
NUM     Thread ID       Client Address 
4       3083553712      127.0.0.1 
5       3075161008      10.14.20.169 
============================= 
kill 5 
Kill Thread 3075161008 
Thread Close 
show 
NUM     Thread ID       Client Address 
4       3083553712      127.0.0.1 
============================= 
 
EmailÀ» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù.