select与poll的区别

简介

在Linux系统中,pollselect是两种常用的I/O多路复用技术,它们都可以用来实现对多个文件描述符的监视,它们之间存在一些区别,本文将详细介绍这两个函数的区别以及各自的使用方法。

区别

1、底层实现

select与poll的区别

pollselect都是基于内核I/O事件通知机制实现的,但它们的底层实现方式略有不同。

- select:select函数通过系统调用与内核进行通信,将需要监视的文件描述符集合传递给内核,然后内核会将这些文件描述符中的可读、可写和异常状态事件返回给用户空间,select函数会一直阻塞,直到某个文件描述符上有事件发生或者超时。

- poll:poll函数也是通过系统调用与内核进行通信,但它与select的区别在于,poll函数允许用户空间一次性传递多个文件描述符,而不仅仅是一个集合,当某个文件描述符上有事件发生时,内核会将该文件描述符及其对应的事件类型返回给用户空间,poll函数同样会一直阻塞,直到某个文件描述符上有事件发生或者超时。

2、可处理的文件描述符数量

select与poll的区别

- select:select函数最多可以同时监视1024个文件描述符(包括标准输入、输出和错误流),如果需要监视更多的文件描述符,可以使用poll函数。

- poll:poll函数没有明确的文件描述符数量限制,但是由于其底层实现方式的局限性,实际可用的文件描述符数量可能会受到系统资源的限制,在处理大量文件描述符时,poll函数可能不如select函数高效。

3、兼容性

- select:select函数是POSIX标准的组成部分,因此在支持POSIX的平台上具有较好的兼容性,在某些不支持POSIX的平台上,select函数可能无法使用。

select与poll的区别

- poll:poll函数同样是POSIX标准的组成部分,因此具有较好的兼容性,与select函数相比,poll函数在某些平台下的实现可能存在差异,导致性能和兼容性方面的问题。

使用方法

1、使用select函数

以下是一个简单的使用select函数实现I/O多路复用的示例:

#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/select.h>
#include <errno.h>
int main() {
    fd_set readfds;
    struct timeval timeout;
    int ret;
    int max_fd = 0;
    int i;
    int fd;
    char buf[1024];
    FD_ZERO(&readfds);
    max_fd = open("test.txt", O_RDONLY);
    FD_SET(max_fd, &readfds);
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;
    while (1) {
        ret = select(max_fd + 1, &readfds, NULL, NULL, &timeout);
        if (ret == -1 && errno != EINTR) {
            perror("select error");
            break;
        } else if (ret == -1 && errno == EINTR) {
            printf("select interrupted by signal
");
            continue;
        } else if (ret == 0) {
            printf("timeout
");
            continue;
        } else if (ret > 0) {
            if (FD_ISSET(max_fd, &readfds)) {
                ret = read(max_fd, buf, sizeof(buf));
                if (ret > 0) {
                    buf[ret] = '\0';
                    printf("read data: %s
", buf);
                } else if (ret == 0) {
                    printf("connection closed
");
                    close(max_fd);
                    break;
                } else {
                    perror("read error");
                    break;
                }
            } else {
                for (i = 3; i <= max_fd; i++) {
                    if (FD_ISSET(i, &readfds)) {
                        ret = read(i, buf, sizeof(buf));
                        if (ret > 0) {
                            buf[ret] = '0';
                            printf("read data from file %d: %s
", i, buf);
                        } else if (ret == 0) {
                            printf("file %d closed
", i);
                            close(i);
                            FD_CLR(i, &readfds);
                        } else {
                            perror("read error");
                            break;
                        }
                    } else if (FD_ISSET(i, &readfds)) {
                        printf("file %d is ready for writing
", i);
                    } else if (FD_ISSET(i, &readfds)) { /* should not happen */} else if (FD_ISSET(i, &readfds)) {} /* ignore errors */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do nothing */} /* do anything else?*/ return 0; };```

原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/121031.html

(0)
K-seoK-seoSEO优化员
上一篇 2023年12月14日 08:28
下一篇 2023年12月14日 08:29

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

免备案 高防CDN 无视CC/DDOS攻击 限时秒杀,10元即可体验  (专业解决各类攻击)>>点击进入