¾²·¹µå°£ ¹öÆÛ °ü¸®
ÃÑ ÆäÀÌÁö ¼ö : 3224

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



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

¾²·¹µå°£ ¹öÆÛ °ü¸®ÀÇ Çʿ伺

´ÙÀ½°ú °°Àº ¿©·¯°³ÀÇ ¸ðµâ·Î ±¸¼ºµÈ ¼­¹ö ½Ã½ºÅÛÀÌ ÀÖ´Ù°í »ý°¢Çغ¸ÀÚ.
 Internet  
           |                          +---------------------------+ 
           |                          |  Worker Module            | 
           |     +-------------+ IPC  |  +--------+  +--------+   | 
 <---------|---->| Comm Module |<-----|->| I/O    |->| Worker |   | 
           |     +-------------+      |  | Thread |  | Thread |   | 
           |                          |  +--------+  +--------+   | 
           |                          +---------------------------+ 
 
Comm Module Àº Ŭ¶óÀ̾ðÆ®ÀÇ ¿äûÀ» ¹Þ¾ÆµéÀδÙ. ¿äû¿¡ ´ëÇÑ Ã³¸®´Â Worker Module ·Î ³Ñ±â°Ô µÈ´Ù. Worker ModuleÀº IPC(12)¸¦ ÅëÇØ¼­ Comm Module·Î ºÎÅÍ Àü´ÞµÈ ¿äû µ¥ÀÌÅ͸¦ ¹Þ°í µ¥ÀÌÅ͸¦ ó¸®ÇÏ°Ô µÈ´Ù.

Work ModuleÀº ³»ºÎÀûÀ¸·Î´Â µ¥ÀÌÅÍ ÀÔÃâ·ÂÀ» ´ã´çÇÏ´Â I/O Thread¿Í ½ÇÁ¦ 󸮸¦ ÇÏ´Â Worker Thread·Î ±¸¼ºÀÌ µÇ¾î ÀÖ´Ù. ÀÌ·¸°Ô Åë½Å ¸ðµâ°ú ´Ù¸¥ ´ÜÀ§ ¸ðµâµéÀ» º°µµÀÇ Process·Î ºÐ¸®ÇÏ°í ¼­·Î IPC¸¦ ÅëÇØ¼­ ¿¬°áÇÏ´Â ±¸Á¶´Â 3TierÀÌ»óµÇ´Â ½Ã½ºÅÛÀ» ±¸¼ºÇϰíÀÚ ÇÒ ¶§ ÈçÈ÷ »ç¿ëµÇ´Â ±¸Á¶´Ù.

ÀÌ ¶§ Worker Module¿¡¼­ Buffer¸¦ »ç¿ëÇÏÁö ¾ÊÀ» °æ¿ì ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. Worker Thread¿¡¼­ ó¸®ÇÒ ¼ö ÀÖ´Â µ¥ÀÌÅÍÀÇ ¾çÀ» ÃʰúÇØ¼­ I/O Thread·Î ºÎÅÍ µ¥ÀÌÅͰ¡ À¯ÀԵǴ °æ¿ìÀÌ´Ù. ÀÌ °æ¿ì ¹®Á¦¿¡ ´ëÇÑ ´ë󹿾ÈÀº ´ÙÀ½ µÎ°¡Áö Á¤µµ°¡ µÉ °ÍÀÌ´Ù.
  1. ±×³É ¼­ºñ½º¸¦ Áö¿¬ÇÑ´Ù.
  2. ¹öÆÛ¸¦ µÎ¾î¼­ ¿äûÀ» ½×¾ÆµÎ°í ÇѰ¡ÇÒ ¶§ ó¸®ÇÑ´Ù.

¿ì¸®´Â ÀÌÁß 2¹øÂ° ¹æ¾È¿¡ ´ëÇØ¼­ ¾Ë¾Æº¸µµ·Ï ÇÒ °ÍÀÌ´Ù. À̰æ¿ì ½Ã½ºÅÛ ±¸¼ºÀº ¾Æ·¡¿Í °°À» °ÍÀÌ´Ù.
 Internet  
           |                        +----------------------------------+ 
           |                        |  Worker Module                   | 
           |   +-------------+ IPC  |  +--------+  +--+   +--------+   | 
 <---------|-->| Comm Module |<-----|->| I/O    |--|bu|-->| Worker |   | 
           |   +-------------+      |  | Thread |  |ff|   | Thread |   | 
           |                        |  +--------+  +--+   +--------+   | 
           |                        +----------------------------------+ 
 
¾²·¹µå Áß°£¿¡ buffer°¡ Á¸ÀçÇÑ´Ù´Â °Í¸¸ Á¦¿ÜÇϰí´Â ù¹ø ±¸¼º°ú ¿ÏÀüÈ÷ µ¿ÀÏÇÏ´Ù.

Buffer ±¸¼º ¹æ¾È

Buffer¸¦ ±¸¼ºÇÏ´Â °ÍÀº ºñ±³Àû ´Ü¼øÇÏ´Ù. queue Çü½ÄÀÇ ÀڷᱸÁ¶¸¦ Çϳª ¸¸µé°í °ü¸®ÇØÁֱ⸸ ÇϸéµÈ´Ù.

±×·¯³ª Çϳª »ý°¢ÇØ¾ß ÇÏ´Â°Ô Àִµ¥ queue¿¡ ÀÚ·á°¡ 0°ÇÀÌ ÀÖÀ» °æ¿ìÀÇ Ã³¸® ¹æ¾ÈÀÌ´Ù. ÀÚ·á°¡ ÇÑ°Ç ÀÌ»ó ÀÖÀ» ¶§¾ß ¹«Á¶°Ç »©¿À±â¸¸ ÇÏ¸é µÇ´Ï ¹®Á¦´Â ¾øÁö¸¸ 0Àϰæ¿ì¿¡´Â ±×·¸°Ô ÇÒ ¼ö°¡ ¾ø´Ù. busy wait »óÅ¿¡ ³õÀ̸鼭 ÀÚ·á°¡ µé¾î¿Ã ¶§±îÁö ±â´Ù¸®´Â ¹æ¹ýÀº ³Ê¹« ºñÈ¿À²ÀûÀÌ´Ù. sleep(2)µîÀÇ ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ ·çÇÁ¸¦ µµ´Â ¹æ¹ýµµ ÀÖ±ä ÇϰÚÁö¸¸ ¿ª½Ã ¹®Á¦°¡ ¸¹Àº ¹æ¹ýÀÌ´Ù.

ÃÖ¼±ÀÇ ¹æ¹ýÀº ÀÚ·á°¡ 0Àϰæ¿ì ÀÚ·á°¡ Çϳª ÀÌ»ó ½×ÀÏ ¶§±îÁö blockµÇµµ·Ï ÇÏ´Â °ÍÀÌ´Ù. ¿©±â¿¡ ´ëÇÑ ¸î°¡Áö ¹æ¾È¿¡ ´ëÇØ¼­ ¾Ë¾Æº¸°í ÀÌÁß ¸¾¿¡ µå´Â°Í Çϳª¸¦ ¼±ÅÃÇϵµ·Ï ÇϰڴÙ.

signal ÀÇ »ç¿ë

buffer·Î ºÎÅÍ µ¥ÀÌÅ͸¦ ¸ðµÎ °¡Á®¿ÔÀ» °æ¿ì sigwait(2)¸¦ È£ÃâÇØ¼­ ºí·°µÇ´Â ¹æ¹ýÀ» »ý°¢ÇÒ ¼ö ÀÖ´Ù. ºñ±³Àû ´Ü¼øÇÑ ¹æ¹ý °°Áö¸¸, ÀڷḦ ½×´Â Ãø¿¡¼­ ¾ðÁ¦ ½Ã±×³ÎÀ» Àü¼ÛÇÒ °ÍÀΰ¡ ÇÏ´Â ¹®Á¦°¡ ³²´Â´Ù. ÀڷḦ ½×À» ¶§ ¸¶´Ù ½Ã±×³ÎÀ» ³¯¸®´Â ¹æ¹ýÀº º°·Î ÁÁ¾Æº¸ÀÌÁö ¾Ê´Â´Ù. ÀÚ·áÀÇ Å©±â°¡ 0ÀÎ ½ÃÁ¡¿¡¼­ »õ·Î¿î µ¥ÀÌÅͰ¡ µé¾î¿ÔÀ» °æ¿ì ½Ã±×³ÎÀ» ³¯¸®µµ·Ï ÇØ¾ß ÇÒ °ÍÀÌ´Ù.

sigwait(2)¸¦ È£ÃâÇÑ ½ÃÁ¡¿¡¼­ »õ·Î¿î µ¥ÀÌÅͰ¡ µé¾î¿Ã °æ¿ì signalÀ» ¹ß»ý½ÃŰ´Â ¹æ¹ýÀ» »ý°¢ÇØ º¼ ¼ö ÀÖÀ» °Í °°´Ù. ±×·¯³ª ÀÌ ¹æ¹ý ¿ª½Ã sigwait(2)¸¦ È£ÃâÇß´Ù´Â °ÍÀ» ´Ù¸¥ ¾²·¹µå¿¡ ¾Ë·ÁÁà¾ß ÇÑ´Ù´Â ¹®Á¦°¡ »ý±ä´Ù. Àü¿ªº¯¼ö¸¦ µÎ°í ÀÌ °ªÀ» º¯°æÇÏ´Â °ÍÀ¸·Î ¾Ë·Á ÁÙ ¼ö ÀÖ°ÚÁö¸¸, µ¿±âÈ­ ¹®Á¦°¡ ¹ß»ýÇÑ´Ù.

À§ ¹æ¹ý ´ë·Î¶ó¸é
  1. Àü¿ªº¯¼öÀÇ °ªÀ» º¯°æÇϰí
  2. sigwait(2)¸¦ È£ÃâÇÏ´Â
¹æ½ÄÀ» »ç¿ëÇØ¾ß ÇÒ °ÍÀε¥, Àü¿ªº¯¼öÀÇ °ªÀ» º¯°æÇϰí sigwait(2)¸¦ È£ÃâÇϱâ Àü¿¡ ´Ù¸¥ ¾²±â ¾²·¹µå¿¡¼­ Àü¿ªº¯¼öÀÇ °ªÀ» Àаí signalÀ» ¹ß»ý½Ãų ¼ö Àֱ⠶§¹®ÀÌ´Ù. ¹®Á¦´Â mutex¸¦ ÀÌ¿ëÇϸé ÇØ°á ÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù. ȤÀº realtime signalÀ» »ç¿ëÇÒ ¼öµµ ÀÖÀ» °ÍÀÌ´Ù.

Mutex ÀÇ »ç¿ë

ÀڷḦ ÀÐÀ» ¶§ Å©±â°¡ 0À̶ó¸é pthread_cond_wait(3) ÇÔ¼ö¸¦ È£ÃâÇØ¼­ ±â´Ù¸°´Ù. ±ú¿ì´Â ½ÃÁ¡Àº ÀڷḦ ³Ö´Â ½ÃÁ¡¿¡¼­ ÀÌÀü ÀÚ·áÀÇ Å©±â°¡ 0ÀÏ °æ¿ì pthread_cond_signal()À» È£ÃâÇÑ´Ù.

¼¼¸¶Æ÷¾îÀÇ »ç¿ë

µ¥ÀÌÅ͸¦ ÀÐÀ» ¶§ ¼¼¸¶Æ÷¾î¸¦ °Ë»çÇÏ´Â ¹æ¹ýÀÌ´Ù. ÀڷḦ ¾ò´Â Ãø¿¡¼­´Â ÃÖ±Ù ÀÚ·áÀÇ Å©±â°¡ 0À̶ó¸é ¼¼¸¶Æ÷¾î °ªÀ» Áõ°¡½ÃŰ°í ±â´Ù¸®°Ô µÉ °ÍÀÌ´Ù. ÀڷḦ ¾ò´Â Ãø¿¡¼­´Â ÀÚ·áÀÔ·ÂÀÌ 0¿¡¼­ Áõ°¡ÇÑ´Ù¸é ¼¼¸¶Æ÷¾î °ªÀ» °¨¼Ò ½ÃŰ´Â ¹æ½ÄÀ» »ç¿ëÇÑ´Ù.

ºñ±³Àû ¸í·áÇÑ ¹æ¹ýÀÌ´Ù.

ÆÄÀÏ Àá±ÝÀÇ »ç¿ë

ÀڷḦ ¾ò´Â Ãø¿¡¼­´Â ÃÖ±ÙÀÇ ÀÚ·áÀÇ Å©±â°¡ 0À̶ó¸é ÆÄÀÏÀ» Àá±×°í Àá±ÝÀÌ Ç®¸± ¶§±îÁö ±â´Ù¸°´Ù. ÀڷḦ ÀÔ·ÂÇÏ´Â Ãø¿¡¼­ ÀڷḦ ÀÔ·ÂÇϰí Àá±ÝÀ» Ç®¸é ºñ·Î¼­ ÀڷḦ ¾ò¾î ¿Ã ¼ö ÀÖÀ» °ÍÀÌ´Ù. ¶ó°í »ý°¢ÇÒ ¼ö ÀÖ°ÚÁö¸¸... ºÒÇàÇϰԵµ fcntl(2)À» ÅëÇÑ ÆÄÀÏÀá±ÝÀº ÇÁ·Î¼¼½º ´ÜÀ§ÀÌ´Ù. Áï ÇϳªÀÇ ÇÁ·Î¼¼½º¿¡¼­´Â ´ÜÁö ÇϳªÀÇ Àá±Ý¸¸À» Á¦¾îÇÒ ¼ö ÀÖÀ» »ÓÀÌ´Ù. ÇÁ·Î¼¼½º°£ ÀӰ迵¿ª ÁöÁ¤À» À§ÇÑ ¸ñÀûÀ¸·Î »ç¿ëÇÒ ¼ö ÀÖ°ÚÁö¸¸, ¾²·¹µå°£ ÀӰ迵¿ª ÁöÁ¤À» À§Çؼ­ »ç¿ëÇϱ⿡´Â ¹®Á¦°¡ ÀÖ´Ù.

Mutex¸¦ ÀÌ¿ëÇÑ ¾²·¹µå°£ µ¥ÀÌÅÍ °øÀ¯

´ÙÀ½Àº ÅÛÇø´À¸·Î ±¸ÇöÇÑ stack Ŭ·¡½º´Ù.
#include <iostream> 
#include <unistd.h> 
#include <stdlib.h> 
#include <string.h> 
#include <stdio.h> 
#include <vector> 
 
using namespace std; 
 
pthread_mutex_t io_mutex = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t io_sync  = PTHREAD_COND_INITIALIZER; 
 
template <typename T1> 
class Queue 
{ 
  private: 
    int MaxSize; 
    int DataIndex; 
    int QueueSize; 
    //T1  *Array; 
    vector<T1> Array; 
    int PushNum; 
  public: 
    // »ý¼ºÀÚ·Î½á µðÆúÆ® ¾Æ±Ô¸ÕÆ®·Î 
    // Å¥ÀÇ »çÀÌÁ ÁöÁ¤Çß´Ù. 
    // ¾Æ±Ô¸ÕÆ®·Î ³Ñ¾î¿Â Å©±â¸¸Å­ Array ÀÇ Å©±â¸¦ 
    // ÇÒ´çÇÏ°í ±âŸ ¸â¹öº¯¼öµéÀÇ °ªÀ» Àû´çÈ÷ ÃʱâÈ­ ÇÑ´Ù. 
    Queue(int size=40) 
    { 
      MaxSize = size; 
      QueueSize = 0; 
      DataIndex = 0; 
      PushNum   = 0; 
      Array.resize(size); 
    } 
    // ¼Ò¸êÀÚ ÀÚ¿øÀ» ÇØÁ¦ÇÑ´Ù. 
    ~Queue() 
    { 
    } 
    // Array¿¡ ¿ø¼Ò¸¦ ÀÔ·ÂÇÑ´Ù. 
    // ¸¸¾à¿¡ Array ÀÇ Å©±â¸¦ ÃʰúÇØ¼­ ¿ø¼Ò°¡ µé¾î°¥°æ¿ì 
    // MaxSize*2 Å©±â¸¸Å­ ¸Þ¸ð¸®ÀÇ Å©±â¸¦ ÀçÇÒ´çÇÑ´Ù. 
    void push_back(T1 x) 
    { 
      pthread_mutex_lock(&io_mutex); 
      if (QueueSize == 0) 
        pthread_cond_signal(&io_sync); 
      if (QueueSize > MaxSize - 1) 
      { 
        MaxSize *= 2; 
        Array.resize(MaxSize); 
      } 
      Array[PushNum%MaxSize] = x; 
      PushNum++; 
      QueueSize++; 
      pthread_mutex_unlock(&io_mutex); 
    } 
    // µ¥ÀÌŸ¸¦ ²¨³½´Ù. 
    T1 pop() 
    { 
      pthread_mutex_lock(&io_mutex); 
      if (QueueSize == 0) 
      { 
        pthread_cond_wait(&io_sync, &io_mutex); 
      } 
      QueueSize--; 
      DataIndex++; 
      pthread_mutex_unlock(&io_mutex); 
      return Array[(DataIndex-1)%MaxSize]; 
    } 
    // Å¥¿¡ ÀÖ´Â µ¥ÀÌŸÀÇ °¹¼ö¸¦ ¾ò¾î¿Â´Ù. 
    int size() 
    { 
      return QueueSize; 
    } 
    // Å¥ÀÇ Å©±â¸¦ ¾ò¾î¿Â´Ù. 
    int capacity() 
    { 
      return MaxSize; 
    } 
    // ¿ø¼Ò¸¦ »èÁ¦ÇÑ´Ù. 
    // ½ÇÁ¦ µ¥ÀÌŸ¸¦ free ½ÃŰÁö´Â ¾Ê°í, Index 
    // °ªµéÀ» Á¶Á¤Çؼ­ »èÁ¦ÇÑ°Í Ã³·³ º¸ÀÌ°Ô ÇÑ´Ù. 
    void clear() 
    { 
      QueueSize = 0; 
      DataIndex = 0; 
      PushNum   = 0; 
    } 
}; 
 

À§ÀÇ ¿¹Á¦ÄÚµå´Â queue.h ·Î ÀúÀåÀ» Çß´Ù. ´ÙÀ½Àº Å×½ºÆ®¸¦ À§ÇÑ ÄÚµå´Ù.
#include <vector> 
#include <unistd.h> 
#include <signal.h> 
#include <queue.h> 
#include <stdio.h> 
 
#include <pthread.h> 
#include <string> 
 
using namespace std; 
 
Queue<string> MQueue(20); 
 
pthread_mutex_t sync_mutex = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t sync_cond  = PTHREAD_COND_INITIALIZER; 
 
void *work_thread(void *rtsnum) 
{ 
  int signum = *((int *)rtsnum); 
 
  // Mutex µ¿±âÈ­ 
  pthread_mutex_lock(&sync_mutex); 
  cout << "Sig Num is " << signum << endl; 
  pthread_cond_signal(&sync_cond); 
  pthread_mutex_unlock(&sync_mutex); 
  // -------------------- 
 
  while(1) 
  { 
    cout << MQueue.size() << " : "<< MQueue.pop(); 
    usleep(10); 
  } 
} 
 
int main(int argc, char **argv) 
{ 
  int thread_num = 5; 
 
  vector<void *(*)(void *)> thread_list; 
  vector<pthread_t> tident(thread_num); 
 
  thread_list.push_back(work_thread); 
 
  for (int i = 0, rtsnum = 1; i < thread_list.size(); i++, rtsnum++) 
  { 
    pthread_mutex_lock(&sync_mutex); 
    pthread_create(&tident[i], NULL, thread_list[i], (void *)&rtsnum); 
    pthread_cond_wait(&sync_cond, &sync_mutex); 
    pthread_mutex_unlock(&sync_mutex); 
  } 
 
  char buf[256]; 
 
  int i = 1; 
  while(1) 
  { 
    sprintf(buf, "My Data %d\n", i); 
    MQueue.push_back(buf); 
    // 5¹ø ·çÇÁ¸¦ µ· ÈÄ¿¡ 1000 msec¸¦ ½¬¾îÁØ´Ù.  
    if ((i % 5) == 0) 
      usleep(1000); 
 
    // 500¹ø ·çÇÁ¸¦ µ· ÈÄ¿¡ 3Ãʸ¦ ½¬¾îÁØ´Ù.     
    if ((i % 500) == 1) 
      sleep(3); 
    i++; 
  } 
} 
 
µ¥ÀÌÅ͸¦ Àд work_thread´Â 10msec ¸¦ °è¼Ó ½¬¸é¼­ µ¥ÀÌÅ͸¦ ÀоîµéÀδÙ. ¹Ý¸é µ¥ÀÌÅ͸¦ ¾²´Â ÃøÀº 5¹ø ·çÇÁµ¹¶§ ¸¶´Ù 1000msec¸¦ ½®´Ù. °á±¹ µ¥ÀÌÅ͸¦ ÀоîµéÀÌ´Â ¼Óµµº¸´Ù µ¥ÀÌÅ͸¦ ¾²´Â ¼Óµµ°¡ ´õ ºü¸£¹Ç·Î, °è¼Ó ÇØ¼­ µ¥ÀÌÅͰ¡ ´Ã¾î³ª°Ô µÉ °ÍÀÌ´Ù. ±×·¯´Ù°¡ 500¹ø ·çÇÁ¸¦ µ· ÈÄ¿¡ 3Ãʸ¦ ½¬¾îÁÖ°Ô µÇ´Âµ¥, ÀÌ ½Ã°£µ¿¾È work_thread´Â ¹öÆÛ¿¡ ÀÖ´Â µ¥ÀÌÅ͸¦ ¸ðµÎ ó¸®ÇÏ°Ô µÈ´Ù. À§ÀÇ ÇÁ·Î±×·¥À» µ¹¸®¸é Å×½ºÆ®°¡ °¡´ÉÇÒ °ÍÀÌ´Ù.
EmailÀ» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù.