多进程共享epoll fd

来源:互联网 发布:linux scp -P 编辑:程序博客网 时间:2024/05/17 07:42

  1. #include <stdlib.h>
  2. #include <strings.h>
  3. #include <sys/epoll.h>
  4. #include <fcntl.h>
  5. #include <unistd.h>
  6. #include <sys/socket.h>
  7. #include <arpa/inet.h>
  8. #include <errno.h>

  9. void setnonblocking(int fd)
  10. {
  11.     int val;

  12.     if ((val = fcntl(fd, F_GETFL)) < 0)
  13.     {
  14.         perror("GETFL");
  15.         exit(1);
  16.     }

  17.     val |= O_NONBLOCK;

  18.     if (fcntl(fd, F_SETFL, val) < 0)
  19.     {
  20.         perror("SETFL");
  21.         exit(1);
  22.     }
  23. }

  24. int main()
  25. {
  26.     int fd, listener, clifd, epfd, i, ret, size;
  27.     struct epoll_event ev, events[16];
  28.     char buf[1024];
  29.     int parent = 1;
  30.     int status;
  31.     int pid;
  32.     
  33.     if ((listener = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  34.     {
  35.         perror("socket");
  36.         exit(1);
  37.     }

  38.     setnonblocking(listener);

  39.     epfd = epoll_create(256);
  40.     if (epfd < 0)
  41.     {
  42.         perror("epoll_create");
  43.         exit(1);
  44.     }

  45.     ev.data.fd = listener;
  46.     ev.events = EPOLLIN | EPOLLET;

  47.     if (epoll_ctl(epfd, EPOLL_CTL_ADD, listener, &ev) < 0)
  48.     {
  49.         perror("epoll_ctl");
  50.         exit(1);
  51.     }
  52.     
  53.     struct sockaddr_in servaddr, cliaddr;
  54.     bzero(&servaddr, sizeof(servaddr));
  55.     servaddr.sin_family = AF_INET;
  56.     servaddr.sin_addr.s_addr = INADDR_ANY;
  57.     servaddr.sin_port = htons(5432);

  58.     if (bind(listener, &servaddr, sizeof(servaddr)) < 0)
  59.     {
  60.         perror("bind");
  61.         exit(1);
  62.     }

  63.     if (listen(listener, 16) < 0)
  64.     {
  65.         perror("listen");
  66.         exit(1);
  67.     }

  68.     for (i = 0; i < 3 && parent; i++)
  69.     {
  70.         switch (fork())
  71.         {
  72.             case -1:
  73.                 perror("fork");
  74.                 exit(1);
  75.             case 0:
  76.                 parent = 0;
  77.                 pid = getpid();
  78.                 break;
  79.             default:
  80.                 break;
  81.         }
  82.     }

  83.     if (parent)
  84.     {
  85.         while ((ret = waitpid(-1, &status, 0)))
  86.         {
  87.             if (ret > 0)
  88.                 printf("child %d has quit with %d...\n", ret, status);
  89.         }
  90.     }

  91.     socklen_t len;
  92.     while (1)
  93.     {
  94.         if ((ret = epoll_wait(epfd, events, 1, 600000)) < 0)
  95.         {
  96.             perror("epoll_wait");
  97.             exit(1);
  98.         }
  99.         else if (ret == 0)
  100.         {
  101.             printf("[%d]600s elapsed...\n", pid);
  102.         }
  103.         else
  104.         {
  105.             printf("\n[%d]%d events checkin\n", pid, ret);
  106.         }

  107.         for (i = 0; i < ret; i++)
  108.         {
  109.             if ((fd = events[i].data.fd) < 0)
  110.             {
  111.                 printf("Invalid fd!\n");
  112.                 exit(1);
  113.             }
  114.             
  115.             if (fd == listener)
  116.             {
  117.                 len = sizeof(cliaddr);
  118.                 clifd = accept(fd, &cliaddr, &len);
  119.                 if (clifd < 0)
  120.                 {
  121.                     perror("accept");
  122.                     continue;
  123.                 }

  124.                 printf("[%d]New connection from %s:%d,fd=%d\n",pid, inet_ntoa(cliaddr.sin_addr), 
  125.                     ntohs(cliaddr.sin_port), clifd);

  126.                 setnonblocking(clifd);
  127.                 ev.data.fd = clifd;
  128.                 ev.events = EPOLLIN | EPOLLET;

  129.                 if (epoll_ctl(epfd, EPOLL_CTL_ADD, clifd, &ev) < 0)
  130.                 {
  131.                     perror("epoll_ctl");
  132.                     exit(1);
  133.                 }
  134.             }
  135.             else if (events[i].events & EPOLLIN)
  136.             {
  137.                 while ((size = recv(fd, buf, sizeof(buf), 0)) > 0)
  138.                 {
  139.                     buf[size] = 0;
  140.                     printf("[%d]%d bytes recved from fd %d:%s\n", pid, size, fd, buf);
  141.                 }

  142.                 printf("[%d]size=%d,fd=%d:%s\n", pid, size, fd, strerror(errno));
  143.                 if (size == 0)
  144.                 {
  145.                     close(fd);
  146.                 }
  147.             }
  148.         }
  149.     }

  150.     return 0;
  151. }






epoll_create这段(46-60)放到子进程里面就没问题了。

0 0
原创粉丝点击