¼ÒÄÏ Àü´ÞÀ» ÅëÇÑ prefork ¼­¹ö ±¸Çö
ÃÑ ÆäÀÌÁö ¼ö : 3224

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



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


¼Ò°³

fork()´Â »õ·Î¿î ÀÚ½ÄÇÁ·Î¼¼½º¸¦ ½ÇÇà½Ã۱â À§Çؼ­ »ç¿ëÇϸç, ´Ù¼öÀÇ Å¬¶óÀÌ¾ðÆ®¸¦ µ¿½Ã¿¡ ó¸®Çϱâ À§Çؼ­ ÀÔÃâ·Â´ÙÁßÈ­¿Í ÇÔ²² °¡Àå ³Î¸® »ç¿ëµÇ´Â ¹æ½ÄÀÌ´Ù.

ÀÌ ¹æ½ÄÀÇ ´ÜÁ¡À̶ó¸é fork()·Î »õ·Î¿î ÇÁ·Î¼¼½º¸¦ »ý¼º½ÃŰ´Â ÀÚü¿¡ ¸¹Àº ºñ¿ëÀÌ µé¾î°£´Ù´Â Á¡ÀÌ µÉ °ÍÀÌ´Ù. ÀÌ ¹®Á¦¸¦ ÇØ°áÇϱâ À§Çؼ­ Àû´çÇÑ ¼ö¸¸Å­ ÇÁ·Î¼¼½º¸¦ ¹Ì¸® ÇÒ´ç½ÃÄÑ ³õ°í, »õ·Î¿î ¿¬°áÀÌ µé¾î¿À¸é ÇÒ´çµÈ ÇÁ·Î¼¼½º¿¡ ¼ÒÄÏÀ» Àü´ÞÇØÁÖ´Â prefork¹æ½ÄÀ» »ç¿ëÇϱ⵵ ÇÑ´Ù. ÀÏÁ¾ÀÇ ÇÁ·Î¼¼½º Ç®À» ¸¸µé¾î¼­ Ȱ¿ë ÇÏ´Â °ÍÀ¸·Î º¼ ¼ö ÀÖ´Ù. ÀÌ ¹®¼­´Â prefork ¿¡ ´ëÇØ¼­ ¼Ò°³ÇÑ´Ù.


´ÙÀ½°ú °°Àº Á¤º¸µéÀ» °¡Áö°í ÀÖ´Ù¸é ¹®¼­ÀÇ Á¢±ÙÀÌ ½¬¿ï °ÍÀÌ´Ù.

¼ÒÄÏ Àü´Þ

prefork ±¸ÇöÀÇ ÇÙ½ÉÀº accept ÇÔ¼ö È£Ãâ ÈÄ ¸¸µé¾îÁø '¼ÒÄÏ ÁöÁ¤ ¹øÈ£'¸¦ ¾î¶»°Ô ÀÌ¹Ì ¸¸µé¾îÁ® ÀÖ´Â ÀÚ½Ä ÇÁ·Î¼¼½º¿¡ Àü´ÞÇÏ´À³Ä¿¡ ÀÖ´Ù. ´ÙÇàÈ÷ ÀÌ¿¡ ´ëÇÑ ÇØ¹ýÀº ³ª¿Í ÀÖ±ä Çѵ¥, ÇØ¹ý ÀÚü°¡ Á» ¸¶¹ýÀûÀÌ´Ù.

¼ÒÄÏ Àü´ÞÀº sendmsg ÇÔ¼ö·Î ÀÌ·ç¾îÁø´Ù. sendmsg ÇÔ¼ö´Â msghdr ±¸Á¶Ã¼·Î µ¥ÀÌÅ͸¦ Àü´ÞÇϴµ¥, msghdr ±¸Á¶Ã¼¿¡ Àü´ÞÇÒ ¼ÒÄÏ ÁöÁ¤ ¹øÈ£ Á¤º¸¸¦ Æ÷ÇÔÇÑ Á¦¾î Á¤º¸¸¦ ÇÔ²² ³Ñ±â´Â ¹æ½ÄÀ¸·Î ÀÌ·ç¾î Áø´Ù. ´ÙÀ½Àº ¼ÒÄÏ Àü´ÞÀ» À§Çؼ­ »ç¿ëÇÏ´Â ÇÔ¼öÀÎ write_fd ÀÌ´Ù.
int write_fd(int fd, void *ptr, size_t nbytes, int sendfd) 
{ 
  struct msghdr    msg; 
  // ºÎ°¡ÀûÀ¸·Î ³Ñ±æ µ¥ÀÌÅÍ ±¸Á¶Ã¼ 
  struct iovec    iov[1]; 
  union { 
    struct cmsghdr cm; 
    char  control[CMSG_SPACE(sizeof(int))]; 
  } control_un; 
  // Á¦¾î Á¤º¸¸¦ Æ÷ÇÔÇÑ cmsghdr ±¸Á¶Ã¼ 
  struct cmsghdr *cmptr; 
 
  msg.msg_control = control_un.control; 
  msg.msg_controllen = sizeof(control_un.control); 
 
  // Á¦¾î Á¤º¸¸¦ ¼³Á¤ÇÑ´Ù. 
  cmptr = CMSG_FIRSTHDR(&msg); 
  cmptr->cmsg_len = CMSG_LEN(sizeof(int)); 
  cmptr->cmsg_level = SOL_SOCKET; 
  cmptr->cmsg_type = SCM_RIGHTS; 
  // Àü¼ÛÇÒ ¼ÒÄÏ ÁöÁ¤ ¹øÈ£¸¦ º¹»çÇÑ´Ù. 
  *((int *) CMSG_DATA(cmptr)) = sendfd; 
  msg.msg_name = NULL; 
  msg.msg_namelen = 0; 
 
  // ±âŸ º¸³¾ µ¥ÀÌÅͰ¡ ÀÖ´Ù¸é ÇÔ²² Àü¼ÛÇÑ´Ù. 
  iov[0].iov_base = ptr; 
  iov[0].iov_len = nbytes; 
  msg.msg_iov = iov; 
  msg.msg_iovlen = 1; 
 
  // sendmsg ÇÔ¼ö·Î µ¥ÀÌÅ͸¦ Àü¼ÛÇÑ´Ù. 
  return(sendmsg(fd, &msg, 0)); 
} 
 

´ÙÀ½Àº ¼ÒÄÏ ÁöÁ¤ ¹øÈ£¸¦ Àбâ À§ÇÑ ÇÔ¼ö read_fd·Î ÀÚ½Ä ÇÁ·Î¼¼½º¿¡¼­ È£Ãâ ÇÑ´Ù.
int read_fd(int fd, char *buf, size_t buflen) 
{ 
  int n; 
  int recvfd; 
  char ptr; 
 
  struct iovec iov[1]; 
  struct cmsghdr *cmptr; 
  struct msghdr msg; 
 
  union { 
    struct cmsghdr cm; 
    char control[CMSG_SPACE(sizeof(int))]; 
  } control_un; 
 
  // Á¦¾î Á¤º¸¸¦ ¼³Á¤ÇÑ´Ù. 
  msg.msg_control = control_un.control; 
  msg.msg_controllen = sizeof(control_un.control); 
  msg.msg_name = NULL; 
  msg.msg_namelen = 0; 
 
  // ºÎ°¡ÀûÀ¸·Î Àоî¿Ã µ¥ÀÌÅÍ   
  iov[0].iov_base = buf; 
  iov[0].iov_len = buflen; 
 
  msg.msg_iov = iov; 
  msg.msg_iovlen = 1; 
 
 
  if ( (n = recvmsg(fd, &msg, 0)) <= 0) 
  { 
    perror("recvmsg Error"); 
    return -1; 
  } 
 
  cmptr = CMSG_FIRSTHDR(&msg);  
  if ((cmptr == NULL)) 
  { 
    perror("CMSG ERROR\n"); 
    return -1; 
  } 
 
  // Á¦¾î Á¤º¸¿¡¼­ ¼ÒÄÏ ÁöÁ¤ ¹øÈ£¸¦ °¡Á®¿Í¼­ ¹ÝȯÇÑ´Ù. 
  recvfd = *((int *) CMSG_DATA(cmptr)); 
  return recvfd; 
} 
 

Å×½ºÆ®¿¡ »ç¿ëÇÒ echo ¼­¹ö

#include <sys/socket.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <stdlib.h> 
 
#define SA struct sockaddr 
 
 
struct _SocketInfo 
{ 
  int pid; 
  int fd; 
  int status; 
}; 
 
int write_fd(int fd, void *ptr, size_t nbytes, int sendfd); 
int prefork_client(int fd); 
int read_fd(int fd); 
 
int main_server(int server_sockfd,  
    struct _SocketInfo *SInfo,  
    struct sockaddr_in clientaddr,  
    int preforknum); 
 
int main(int argc, char **argv) 
{ 
    char buf_in[80]; 
    int state; 
    int clilen; 
    int n,i,pid; 
    int preforknum; 
    int ppid; 
    int sv[2]; 
    struct _SocketInfo *SocketArray; 
 
    int server_sockfd, client_sockfd; 
    struct sockaddr_in clientaddr, serveraddr; 
 
    if (argc != 2) 
    { 
      fprintf(stderr, "Usage: %s [prefork#]\n", argv[0]); 
      return 1; 
    } 
    preforknum = atoi(argv[1]); 
 
    if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
    { 
        perror("Error"); 
        return 1; 
    } 
    bzero(&serveraddr, sizeof(serveraddr)); 
 
    serveraddr.sin_family = AF_INET; 
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    serveraddr.sin_port = htons(8083); 
 
    bind(server_sockfd, (SA *)&serveraddr, sizeof(serveraddr)); 
    if ((state = listen(server_sockfd, 5))<0) 
    { 
        perror("listen error: "); 
        exit(0); 
    } 
 
    if(preforknum > 10) 
    { 
      fprintf(stderr,"Max preforknum is 10\n"); 
      exit(0); 
    } 
    ppid = getpid(); 
 
    // Socket Infomation Array 
    SocketArray = (void *)malloc(sizeof(struct _SocketInfo)*preforknum); 
    memset((void *)SocketArray, 0x00, sizeof(struct _SocketInfo)*preforknum); 
 
    for (i = 0; i < preforknum; i++) 
    { 
      socketpair(AF_LOCAL, SOCK_STREAM, AF_LOCAL, sv); 
      pid = fork(); 
      if (pid < 0) 
      { 
        perror("fork error"); 
        exit(0); 
      } 
      if (pid == 0) 
      { 
        dup2(sv[0], 0); 
        close(sv[1]); 
        close(sv[0]); 
        close(server_sockfd); 
        prefork_client(0); 
      } 
      else 
      { 
        close(sv[0]); 
        SocketArray[i].pid    = pid;  
        SocketArray[i].fd     = sv[1]; 
        SocketArray[i].status = 1;   
      } 
    } 
    main_server(server_sockfd, SocketArray, clientaddr, preforknum); 
} 
 
int write_fd(int fd, void *ptr, size_t nbytes, int sendfd) 
{ 
  struct msghdr    msg; 
  struct iovec    iov[1]; 
  union { 
    struct cmsghdr cm; 
    char  control[CMSG_SPACE(sizeof(int))]; 
  } control_un; 
  struct cmsghdr *cmptr; 
 
  msg.msg_control = control_un.control; 
  msg.msg_controllen = sizeof(control_un.control); 
 
  cmptr = CMSG_FIRSTHDR(&msg); 
  cmptr->cmsg_len = CMSG_LEN(sizeof(int)); 
  cmptr->cmsg_level = SOL_SOCKET; 
  cmptr->cmsg_type = SCM_RIGHTS; 
  *((int *) CMSG_DATA(cmptr)) = sendfd; 
  msg.msg_name = NULL; 
  msg.msg_namelen = 0; 
 
  iov[0].iov_base = ptr; 
  iov[0].iov_len = nbytes; 
  msg.msg_iov = iov; 
  msg.msg_iovlen = 1; 
  return(sendmsg(fd, &msg, 0)); 
} 
 
int read_fd(int fd) 
{ 
  int n; 
  int recvfd; 
  char ptr; 
 
  struct iovec iov[1]; 
  struct cmsghdr *cmptr; 
  struct msghdr msg; 
 
  union { 
    struct cmsghdr cm; 
    char control[CMSG_SPACE(sizeof(int))]; 
  } control_un; 
 
 
  msg.msg_control = control_un.control; 
  msg.msg_controllen = sizeof(control_un.control); 
  msg.msg_name = NULL; 
  msg.msg_namelen = 0; 
 
  iov[0].iov_base = (void *)&ptr; 
  iov[0].iov_len = 1; 
  msg.msg_iov = iov; 
  msg.msg_iovlen = 1; 
 
 
  if ( (n = recvmsg(fd, &msg, 0)) <= 0) 
  { 
    perror("recvmsg Error"); 
    return -1; 
  } 
 
  cmptr = CMSG_FIRSTHDR(&msg);  
  if ((cmptr == NULL)) 
  { 
    perror("CMSG ERROR\n"); 
    return -1; 
  } 
  recvfd = *((int *) CMSG_DATA(cmptr)); 
  return recvfd; 
} 
 
int main_server(int server_sockfd,  
      struct _SocketInfo *SocketArray,  
      struct sockaddr_in clientaddr,  
      int preforknum) 
{ 
    int clilen; 
    int client_sockfd; 
    int i; 
    char ptr; 
    int n; 
    int maxfd; 
    fd_set readfds, allfds; 
    int data; 
    FD_ZERO(&readfds); 
    FD_SET(server_sockfd, &readfds); 
    for (i = 0; i < preforknum; i++) 
    { 
      FD_SET(SocketArray[i].fd, &readfds); 
      maxfd = SocketArray[i].fd; 
      printf("socketpair fd %d\n", maxfd); 
    } 
 
    printf("%d\n", maxfd+1); 
    allfds = readfds; 
    while(1) 
    { 
        readfds = allfds; 
        clilen = sizeof(clientaddr); 
 
        printf("select Wait\n"); 
        n = select(maxfd + 1, &readfds, (fd_set *)0, (fd_set *)0, NULL); 
        printf("select Wait End %d\n", n); 
        if (n < 0) continue; 
 
        if (FD_ISSET(server_sockfd, &readfds)) 
        { 
           printf("ACCEPT\n"); 
           if ((client_sockfd = accept(server_sockfd, (SA *)&clientaddr, (size_t *)&clilen)) ==-1) 
           { 
              perror("accept error:"); 
              close(client_sockfd); 
           } 
           else 
           { 
             for (i = 0; i < preforknum; i++) 
             { 
                if(SocketArray[i].status) 
                { 
                  printf("SocketSend pid(%d) -> %d\n", SocketArray[i].pid, client_sockfd); 
                  write_fd(SocketArray[i].fd, &ptr, 1, client_sockfd); 
                  SocketArray[i].status = 0; 
                  close(client_sockfd); 
                  break; 
                } 
              } 
              if (i == preforknum) 
              { 
                fprintf(stderr, "max Client error\n"); 
                close(client_sockfd); 
              } 
           } 
        } 
 
        for (i = 0; i < preforknum; i++) 
        { 
          if(FD_ISSET(SocketArray[i].fd, &readfds)) 
          { 
            printf("OK Chield Data\n"); 
            read(SocketArray[i].fd, (void *)&data, sizeof(data)); 
            printf("(%d) : Read Data %d\n", SocketArray[i].fd, data); 
            if(data == 0) 
            { 
              SocketArray[i].status = 1; 
            } 
          } 
        } 
    } 
} 
 
int prefork_client(int fd) 
{ 
    int n; 
  char buf_in[80]={0x00,}; 
  int sockfd; 
  int msg = 0; 
  printf("Child PID %d\n", getpid()); 
 
  while(1) 
  { 
    sockfd = read_fd(fd); 
    for(;;) 
    { 
      if ((n = read(sockfd, buf_in, 79)) > 0) 
      { 
        write(sockfd, buf_in, strlen(buf_in)); 
      } 
      else 
      { 
        printf("Client Socket Close\n"); 
        write(fd, (void *)&msg, sizeof(msg)); 
        close(sockfd); 
        break; 
      } 
      memset(buf_in, 0x00, sizeof(buf_in)); 
    }  
  } 
} 
 

exec ÀÀ¿ë

fork(2)¹æ½Ä¿¡¼­ ¼ÒÄÏÀü´ÞÀÌ ¼º°øÀûÀ¸·Î ÀÌ·ç¾îÁö´Â°É È®ÀÎÇß´Ù. ÀÌÁ¦ exec(2)¿¡¼­µµ °¡´ÉÇÑÁö È®ÀÎÇØ º¸·Á ÇÑ´Ù. À§ÀÇ ÇÁ·Î±×·¥À» ¾à°£ ¼öÁ¤Çؼ­ Ŭ¶óÀ̾ðÆ®ÀÇ ¿¬°áÀ» acceptÇϰí prefork¸¦ ÇÏ´Â socketmain.c ÇÁ·Î±×·¥°ú preforkµÇ¾î¼­ µ¥ÀÌÅ͸¦ ó¸®ÇÏ´Â prefork.c¶ó´Â ÇÁ·Î±×·¥À» ¸¸µé¾ú´Ù.

socketmain.c´Â À§ÀÇ fork ¹öÁ¯¿¡¼­ ¾Æ·¡ÀÇ ¶óÀθ¸ ¼öÁ¤Çß´Ù.
if (pid == 0) 
{ 
  dup2(sv[0], 0); 
  close(sv[1]); 
  close(sv[0]); 
  close(server_sockfd); 
  prefork_client(0); 
} 
¸¦ 
if (pid == 0) 
{ 
  dup2(sv[0], 0); 
  close(sv[1]); 
  close(sv[0]); 
  close(server_sockfd); 
  execl("./client", "client", NULL); 
} 
·Î 
 

´ÙÀ½Àº prefork.c ·Î int prefork_client ÇÔ¼ö¸¦ ¾à°£ ¼öÁ¤Çؼ­ Àç ÀÛ¼ºÇß´Ù.
#include <sys/socket.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <stdlib.h> 
 
#define SA struct sockaddr 
 
int read_fd(int fd); 
int main(int argc, char **argv) 
{ 
  int n; 
  char buf_in[80]={0x00,}; 
  int sockfd; 
  int msg = 0; 
  printf("Child PID %d\n", getpid()); 
  int fd = 0; 
 
  while(1) 
  { 
    sockfd = read_fd(fd); 
    for(;;) 
    { 
      if ((n = read(sockfd, buf_in, 79)) > 0) 
      { 
        write(sockfd, buf_in, strlen(buf_in)); 
      } 
      else 
      { 
        printf("Client Socket Close\n"); 
        write(fd, (void *)&msg, sizeof(msg)); 
        close(sockfd); 
        break; 
      } 
      memset(buf_in, 0x00, sizeof(buf_in)); 
    }  
  } 
} 
 
int read_fd(int fd) 
{ 
  int n; 
  int recvfd; 
  char ptr; 
 
  struct iovec iov[1]; 
  struct cmsghdr *cmptr; 
  struct msghdr msg; 
 
  union { 
    struct cmsghdr cm; 
    char control[CMSG_SPACE(sizeof(int))]; 
  } control_un; 
 
 
  msg.msg_control = control_un.control; 
  msg.msg_controllen = sizeof(control_un.control); 
  msg.msg_name = NULL; 
  msg.msg_namelen = 0; 
 
  iov[0].iov_base = (void *)&ptr; 
  iov[0].iov_len = 1; 
  msg.msg_iov = iov; 
  msg.msg_iovlen = 1; 
 
 
  if ( (n = recvmsg(fd, &msg, 0)) <= 0) 
  { 
    perror("recvmsg Error"); 
    return -1; 
  } 
 
  cmptr = CMSG_FIRSTHDR(&msg);  
  if ((cmptr == NULL)) 
  { 
    perror("CMSG ERROR\n"); 
    return -1; 
  } 
  recvfd = *((int *) CMSG_DATA(cmptr)); 
  return recvfd; 
} 
 

Å×½ºÆ® ÇØº» °á°ú ¹®Á¦¾øÀÌ ÀÛµ¿µÊÀ» È®ÀÎÇÒ ¼ö ÀÖ¾ú´Ù.

Âü°í¹®Çå

EmailÀ» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù.