目录
使用select实现IO多路复用
使用select实现IO多路复用,就可以读取同一进程多次输入,不受读取其他进程时,read的阻塞,读取只阻塞在select
代码实现
1.创建有名管道mkfifo fifo1 fifo2 fifo3
2. read.c —3进程写入
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
/*select*/
#include <sys/select.h>
/*exit*/
#include <stdlib.h>
int main(){
//1.创建文件mkfifo fifo1 fifo2 fifo3
//2.打开文件
int fd1 = open("fifo1", O_RDONLY);
int fd2 = open("fifo2", O_RDONLY);
int fd3 = open("fifo3", O_RDONLY);
char buff1[32] = {0};
char buff2[32] = {0};
char buff3[32] = {0};
//1.创建文件描述符集合
fd_set readfds;
FD_ZERO(&readfds);//清空集合
fd_set readfds_temp;用来备份原集合的
FD_ZERO(&readfds_temp);//清空集合
//2.记录表中最大的文件描述符
int max_fd = 0;
//3.将fd添加到集合中
FD_SET(fd1,&readfds);
max_fd=(max_fd>fd1?max_fd:fd1);//找最大的文件描述符
FD_SET(fd2,&readfds);
max_fd=(max_fd>fd2?max_fd:fd2);//
FD_SET(fd3,&readfds);
max_fd=(max_fd>fd3?max_fd:fd3);//
while(1){
//select会将没有就绪的文件描述符擦除
readfds_temp=readfds;
//4.select找就绪的文件描述符
//成功 返回就绪的文件描述符的个数
if (-1==(select(max_fd+1,&readfds_temp,NULL,NULL,NULL)))
{
perror("select error");
exit(-1);
}
if(FD_ISSET(fd1, &readfds_temp))
{
memset(buff1, 0, 32);
read(fd1, buff1, 32);
printf("buff1 = %s\n", buff1);
}
if(FD_ISSET(fd2, &readfds_temp))
{
memset(buff2, 0, 32);
read(fd2, buff2, 32);
printf("buff2 = %s\n", buff2);
}
if(FD_ISSET(fd3, &readfds_temp))
{
memset(buff3, 0, 32);
read(fd3, buff3, 32);
printf("buff3 = %s\n", buff3);
}
}
close(fd1);
close(fd2);
close(fd3);
return 0;
}
3.01write.c 02write.c 03write.c
3个写端,只需修改打开的管道文件描述符
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{ //修改这fifo1/fifo2/fifo3
int fd = open("fifo1", O_WRONLY);
char buff[32] = {0};
while (1)
{
fgets(buff, 32, stdin);
buff[strlen(buff) - 1] = '\0';
write(fd, buff, 32);
}
close(fd);
return 0;
}