非阻塞IO简介和代码实例

接上篇

阻塞IO、非阻塞IO、IO多路复用和信号驱动IO简介-CSDN博客文章浏览阅读90次。阻塞IO、非阻塞IO、IO多路复用和信号驱动IO简介https://blog.csdn.net/CSDN_DU666666/article/details/139598410?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22139598410%22%2C%22source%22%3A%22CSDN_DU666666%22%7D

以读操作为例,当进程执行读操作的时候,如果缓冲区内有内容,则读取内容继续执行。

如果缓冲区没有内容,则立即返回一个错误,而非让进程进入休眠状态。

但是,这种操作需要配合一个循环不停的测试是否有数据可读,这种操作十分浪费CPU,一般不推荐。

有些函数本身自带非阻塞标志位

eg: waitpid的WHOHANG

        recv和recvfrom的MSG_DONTWAIT O_NONBLOCK

但对于大部分的函数并没有非阻塞标志位,可以使用fcntl函数设置非阻塞标志位

功能:
	控制文件描述符状态
头文件:
	#include <unistd.h>
	#include <fcntl.h>
函数原型:
	int fcntl(int fd, int cmd, ... /* arg */ );
参数:
	fd	文件描述符
	cmd	要控制的方式
		F_GETFL	获取文-件描述符的状态 arg被忽略
		F_SETFL 设置文件描述符的状态 arg为int类型
			文件描述符的状态 O_NONBLOCK 表示非阻塞
	...	可变参 有没有 以及什么类型 都取决于 cmd
返回值:
	cmd是 F_GETFL 成功 返回文件状态标志位 失败返回-1 重置错误码 
	cmd是 F_SETFL 成功 返回 0 失败返回-1 重置错误码

使用fcntl设置非阻塞:

int flag = fcntl(fd,F_GETFL);

flag|=O_NONBLOCK;

fcntl(fd,F_SETFL,flag);

首先创建三个管道文件

指令:mkfifo fifo1  

          mkfifo fifo2

          mkfifo fifo3

service.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, const char *argv[])
{
    int fd1, fd2, fd3;
    if (-1 == (fd1 = open("fifo1", O_RDONLY)))
    {
        PRINT_ERR("open fifo1 error");
    }
    if (-1 == (fd2 = open("fifo2", O_RDONLY)))
    {
        PRINT_ERR("open fifo2 error");
    }
    if (-1 == (fd3 = open("fifo3", O_RDONLY)))
    {
        PRINT_ERR("open fifo3 error");
    }
    char buff[128] = {0};
    int flag = 0;
    flag = fcntl(fd1, F_GETFL);
    flag |= O_NONBLOCK;
    fcntl(fd1, F_SETFL, flag);

    flag = fcntl(fd2, F_GETFL);
    flag |= O_NONBLOCK;
    fcntl(fd2, F_SETFL, flag);

    flag = fcntl(fd3, F_GETFL);
    flag |= O_NONBLOCK;
    fcntl(fd3, F_SETFL, flag);
    while (1)
    {
        sleep(1);
        memset(buff, 0, sizeof(buff));
        read(fd1, buff, sizeof(buff));
        printf("buff1=%s\n", buff);
        memset(buff, 0, sizeof(buff));
        read(fd2, buff, sizeof(buff));
        printf("buff2=%s\n", buff);
        memset(buff, 0, sizeof(buff));
        read(fd3, buff, sizeof(buff));
        printf("buff3=%s\n", buff);
        sleep(1); // 此处sleep(1)是为了看现象 防止刷屏
    }
    close(fd1);
    close(fd2);
    close(fd3);
    return 0;
}

client.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main(int argc, const char *argv[]){
  int fd = open("fifo1", O_WRONLY);//fifo2 fiof3
    char buff[128] = {0};

    while(1){
        memset(buff, 0, 128);
             printf("请输入:");
        fgets(buff, 128, stdin);
        buff[strlen(buff)-1] = '\0';
        write(fd, buff, 128);
    }
    close(fd);

    return 0;
}

相关推荐

  1. 高级IO——阻塞IOselect

    2024-06-14 01:14:01       16 阅读
  2. 阻塞IO

    2024-06-14 01:14:01       8 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-14 01:14:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-14 01:14:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-14 01:14:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-14 01:14:01       18 阅读

热门阅读

  1. 【系统学C++】从C语言到C++(三)

    2024-06-14 01:14:01       8 阅读
  2. MySQL CHECK约束

    2024-06-14 01:14:01       7 阅读