select
- 功能:可以将多个阻塞点变成一个阻塞点
- 原型:
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
- 参数:
1)nfds,监听的最大的文件描述符 maxfd + 1
2)readfds
3)writefds
4)exceptfds
5)timeout - 返回值:
成功:返回就绪事件的数目,若超时,返回0
失败:返回-1,并会设置errno - 同步的 I/O 多路复用

- 缺陷
a.监听的文件描述符的个数是有限的
b.当 select 返回时,还得遍历fd_set,找到就绪的文件描述符 - 补充
strtok:
char *strtok(char *str, const char *delim);
str:
a.没加const,传入传出参数
b.设NULL:从上次停止的地方继续分割原字符串
delim:分隔符,要扔掉的 - DO
#include <func.h>
#define MAXLINE 256
int main(int argc, char* argv[]) {
int fd1 = open("pipe1", O_WRONLY);
if (fd1 == -1) {
error(1, errno, "open pipe1");
}
int fd2 = open("pipe2", O_RDONLY);
if (fd2 == -1) {
error(1, errno, "open pipe2");
}
printf("Established\n");
char recvline[MAXLINE];
char sendline[MAXLINE];
fd_set mainfds;
FD_ZERO(&mainfds);
FD_SET(STDIN_FILENO, &mainfds);
int maxfds = STDIN_FILENO;
FD_SET(fd2, &mainfds);
if (fd2 > maxfds) {
maxfds = fd2;
}
while (1) {
fd_set readfds = mainfds;
int events = select(maxfds + 1, &readfds, NULL, NULL, NULL);
switch (events) {
case -1:
error(1, errno, "select");
case 0:
printf("TIMEOUT\n");
continue;
default:
if (FD_ISSET(STDIN_FILENO, &readfds)) {
fgets(sendline, MAXLINE, stdin);
write(fd1, sendline, strlen(sendline) + 1);
}
if (FD_ISSET(fd2, &readfds)) {
int nbytes = read(fd2, recvline, MAXLINE);
if (!nbytes) {
goto end;
} else if (nbytes == -1) {
error(1, errno, "read pipe2");
}
printf("from p2: %s", recvline);
}
}
}
end:
close(fd1);
close(fd2);
return 0;
}
#include <func.h>
#define MAXLINE 256
int main(int argc, char* argv[]) {
int fd1 = open("pipe1", O_RDONLY);
if (fd1 == -1) {
error(1, errno, "open pipe1");
}
int fd2 = open("pipe2", O_WRONLY);
if (fd2 == -1) {
error(1, errno, "open pipe2");
}
printf("Established\n");
char recvline[MAXLINE];
char sendline[MAXLINE];
fd_set mainfds;
FD_ZERO(&mainfds);
FD_SET(STDIN_FILENO, &mainfds);
int maxfds = STDIN_FILENO;
FD_SET(fd1, &mainfds);
if (fd1 > maxfds) {
maxfds = fd1;
}
while (1) {
fd_set readfds = mainfds;
int events = select(maxfds + 1, &readfds, NULL, NULL, NULL);
switch (events) {
case -1:
error(1, errno, "select");
case 0:
printf("TIMEOUT\n");
continue;
default:
if (FD_ISSET(STDIN_FILENO, &readfds)) {
fgets(sendline, MAXLINE, stdin);
write(fd2, sendline, strlen(sendline) + 1);
}
if (FD_ISSET(fd1, &readfds)) {
int nbytes = read(fd1, recvline, MAXLINE);
if (!nbytes) {
goto end;
} else if (nbytes == -1) {
error(1, errno, "read pipe1");
}
printf("from p1: %s", recvline);
}
}
}
end:
close(fd1);
close(fd2);
return 0;
}