事件驱动reactor的原理与实现

fdset 集合:(就是说)

  • fd_set是一个位图(bitmap)结构
  • 每个位代表一个文件描述符
  • 0表示不在集合中,1表示在集合中

fd_set结构(简化):
[0][1][2][3][4][5]...[1023]
 0  0  1  0  1  0     0
   ↑     ↑
   |     |
sockfd  clientfd

// select方式
fd_set rfds;
select(maxfd+1, &rfds, NULL, NULL, NULL);

// epoll方式
struct epoll_event events[1024];
epoll_wait(epfd, events, 1024, -1);

 maxfd就是1023,rfds就是read fds 读事件,

select的返回值是就绪事件操作如下:

int ret = select(nfds, &readfds, &writefds, &exceptfds, &timeout);
if (ret > 0) {
    // 有事件发生
    printf("有 %d 个文件描述符就绪\n", ret);
    
    // 检查读事件
    if (FD_ISSET(sockfd, &readfds)) {
        // 处理读事件
    }
    
    // 检查写事件
    if (FD_ISSET(sockfd, &writefds)) {
        // 处理写事件
    }
    
    // 检查异常事件
    if (FD_ISSET(sockfd, &exceptfds)) {
        // 处理异常事件
    }
}

 fd操作如下:

// 清空集合
FD_ZERO(&rfds);
// 结果:[0][0][0][0][0]...[0]

// 添加fd到集合
FD_SET(sockfd, &rfds);
// 例如sockfd=2:[0][0][1][0][0]...[0]

// 从集合中删除fd
FD_CLR(sockfd, &rfds);
// 例如sockfd=2:[0][0][0][0][0]...[0]

// 检查fd是否在集合中
FD_ISSET(sockfd, &rfds);
// 返回1表示在集合中,0表示不在

a) 一个连接一个线程:

优点:
- 实现简单
- 逻辑清晰
- 适合并发量小的场景

缺点:
- 线程资源消耗大
- 线程切换开销大
- 不适合高并发

select

优点:
- 单线程处理多连接
- 资源消耗小
- 适合中等并发

缺点:
- 效率较低
- 连接数有限
- 需要轮询

epoll

优点:
- 高效的事件通知
- 适合高并发
- 资源消耗小

缺点:
- 实现较复杂
- 需要系统支持

// 多线程方式
void *client_thread(void *arg) {
    int clientfd = *(int *)arg;
    while (1) {
        recv(clientfd, buffer, 1024, 0);
        // 处理数据
    }
}

// epoll方式
while (1) {
    epoll_wait(epfd, events, 1024, -1);
    for (i = 0; i < nready; i++) {
        if (events[i].data.fd == sockfd) {
            // 处理新连接
        } else {
            // 处理数据
        }
    }
}
// 方式1:一个连接一个线程
while (1) {
    int clientfd = accept(sockfd, ...);
    pthread_t thid;
    pthread_create(&thid, NULL, client_thread, &clientfd);
}

// 方式2:单线程处理多个连接(select)
while (1) {
    select(maxfd+1, &rset, NULL, NULL, NULL);
    // 处理多个连接
}

// 方式3:单线程处理多个连接(epoll)
while (1) {
    epoll_wait(epfd, events, 1024, -1);
    // 处理多个连接
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值