epoll应用的一个例子

代码:
/*
 *  PipeTest by Davide Libenzi ( Epoll performace tester )
 *  Copyright (C) 1999,..,2003  Davide Libenzi
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  Davide Libenzi <davidel@xmailserver.org>
 *
 *
 *  You need either a never glibc or the epoll library available here :
 *
 *  http://www.xmailserver.org/linux-patches/nio-improve.html#sys_epoll
 *
 *  to build this source file. To build :
 *
 *  gcc -o pipetest pipetest.c -lepoll
 *
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/signal.h>
#include <sys/resource.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <sys/epoll.h>


#define RUNTIMES 16


static int count, writes, fired;
static int *pipes;
static int num_pipes, num_active, num_writes;
static int epfd;
static struct epoll_event *events;



unsigned long long getustime(void) {
   struct timeval tm;

   gettimeofday(&tm, NULL);
   return (unsigned long long) tm.tv_sec * 1000000ULL + (unsigned long long) tm.tv_usec;
}


void read_cb(int fd, int idx) {
   int widx = idx + num_active + 1;
   u_char ch;

   if (read(fd, &ch, sizeof(ch)))
      count++;
   else
      fprintf(stderr, "false read event: fd=%d idx=%d/n", fd, idx);
   if (writes) {
      if (widx >= num_pipes)
         widx -= num_pipes;
      write(pipes[2 * widx + 1], "e", 1);
      writes--;
      fired++;
   }
}


int run_once(long *work, unsigned long long *tr) {
   int i, res;
   unsigned long long ts, te;

   fired = 0;
   for (i = 0; i < num_active; i++, fired++)
      write(pipes[i * 2 + 1], "e", 1);

   count = 0;
   writes = num_writes;

   ts = getustime();
   do {
      res = epoll_wait(epfd, events, num_pipes, 0);
      for (i = 0; i < res; i++)
         read_cb(pipes[2 * events[i].data.u32], events[i].data.u32);
   } while (count != fired);
   te = getustime();

   *tr = te - ts;
   *work = count;

   return (0);
}


int main (int argc, char **argv) {
   struct rlimit rl;
   int i, c;
   long work;
   unsigned long long tr;
   int *cp;
   struct epoll_event ev;
   extern char *optarg;

   num_pipes = 100;
   num_active = 1;
   num_writes = num_pipes;
   while ((c = getopt(argc, argv, "n:a:w:")) != -1) {
      switch (c) {
      case 'n':
         num_pipes = atoi(optarg);
         break;
      case 'a':
         num_active = atoi(optarg);
         break;
      case 'w':
         num_writes = atoi(optarg);
         break;
      default:
         fprintf(stderr, "Illegal argument /"%c/"/n", c);
         exit(1);
      }
   }

   rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50;
   if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
      perror("setrlimit");
      exit(1);
   }

   events = calloc(num_pipes, sizeof(struct epoll_event));
   pipes = calloc(num_pipes * 2, sizeof(int));
   if (events == NULL || pipes == NULL) {
      perror("malloc");
      exit(1);
   }

   if ((epfd = epoll_create(num_pipes)) == -1) {
      perror("epoll_create");
      exit(1);
   }

   for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
      if (pipe(cp) == -1) {
         perror("pipe");
         exit(1);
      }
      fcntl(cp[0], F_SETFL, fcntl(cp[0], F_GETFL) | O_NONBLOCK);
   }

   for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
      ev.events = EPOLLIN;
      ev.data.u32 = i;
      if (epoll_ctl(epfd, EPOLL_CTL_ADD, cp[0], &ev) < 0) {
         perror("epoll_ctl");
         exit(1);
      }
   }

   for (i = 0; i < RUNTIMES; i++) {
      run_once(&work, &tr);
      if (!work)
         exit(1);
      fprintf(stdout, "%lf/n", (double) tr / (double) work);
   }

   exit(0);
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C++中,我们可以使用`boost::asio`库,它提供了对epoll的支持。以下是一个简单的例子,展示了如何使用`boost::asio`和epoll来创建一个非阻塞TCP服务器: ```cpp #include <boost/asio.hpp> #include <iostream> using boost::asio::ip::tcp; class EpollServer { public: EpollServer(boost::asio::io_context& io_context) : acceptor_(io_context, tcp::endpoint(tcp::v4(), 8080)), socket_() { // 将socket_添加到epoll实例中 do_accept(); } private: void do_accept() { acceptor_.async_accept(socket_, [this](const boost::system::error_code& ec) { if (!ec) { // 新的连接已建立,将其注册到epoll start_connection(socket_); // 继续接受新的连接 do_accept(); } else { // 出错或连接关闭,从epoll移除并退出 handle_error(ec); } }); } void start_connection(tcp::socket& socket) { // 在这里处理新连接,例如读取数据、发送响应等 std::cout << "Accepted connection from " << socket.remote_endpoint() << std::endl; // 在合适的地方使用epoll来处理这个socket的读写事件 } void handle_error(const boost::system::error_code& ec) { std::cerr << "Accept failed: " << ec.message() << std::endl; // 如果需要清理资源,可以在这里移除socket_ } tcp::acceptor acceptor_; tcp::socket socket_; }; int main() { try { boost::asio::io_context io_context; EpollServer server(io_context); // 开始异步I/O循环 io_context.run(); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << std::endl; } return 0; } ``` 在这个例子中,`do_accept()`函数使用了`async_accept()`函数,并通过lambda表达式回调处理成功接受的连接。一旦连接建立,`start_connection()`会被调用,其中可以设置epoll监听socket以处理读写事件。请注意,在实际应用中,你需要根据具体的业务逻辑实现`start_connection`中的具体功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值