select
基础概念及应用select
是 Linux 系统中用于 I/O 多路复用的一个系统调用。它允许单个进程处理多个 I/O 操作,常用于串口通信等场景。通过 select
,程序可以监视多个文件描述符(例如串口设备),并在这些文件描述符中的任何一个准备好进行 I/O 操作时得到通知。
select
也在其他 Unix-like 系统上得到支持。select
可以监视三种类型的文件描述符:可读、可写和异常状态。select
来实现非阻塞的数据读写。select
来处理多个客户端连接。以下是一个简单的使用 select
监听串口数据的示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/select.h>
#include <errno.h>
int main() {
int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY); // 打开串口设备
if (fd == -1) {
perror("open");
return -1;
}
fd_set readfs; // 文件描述符集合
struct timeval timeout; // 超时设置
while (1) {
FD_ZERO(&readfs); // 清空文件描述符集合
FD_SET(fd, &readfs); // 将串口设备添加到集合中
timeout.tv_sec = 5; // 设置超时时间为5秒
timeout.tv_usec = 0;
int ret = select(fd + 1, &readfs, NULL, NULL, &timeout); // 监听串口设备
if (ret == -1) {
perror("select");
break;
} else if (ret == 0) {
printf("select timeout\n"); // 超时处理
continue;
}
if (FD_ISSET(fd, &readfs)) { // 判断串口设备是否有数据可读
char buffer[256];
int len = read(fd, buffer, sizeof(buffer)); // 读取数据
if (len > 0) {
buffer[len] = '\0';
printf("Received data: %s\n", buffer); // 处理接收到的数据
}
}
}
close(fd); // 关闭串口设备
return 0;
}
select
返回后,文件描述符仍然不可读写。select
监听大量文件描述符时性能下降。select
本身有一定的性能开销,特别是在处理大量文件描述符时。epoll
(在 Linux 上)。总之,select
是一个强大且灵活的 I/O 多路复用工具,在 Linux 串口通信等领域有广泛应用。
领取专属 10元无门槛券
手把手带您无忧上云