• read函数


    ssize_t read(int fildes, void *buf, size_t nbyte);
    返回值:
      > 0: 实际读到的字节数
      = 0: 读完数据(读文件, 管道, socket末尾-->对端关闭, 对端未关闭会一直等待)
      -1: 异常:
        errno == EINTR被信号中断, 重启或者退出
        errno == EAGAIN或者EWOULDBLOCK以非阻塞方式读, 并且没有数据
        其他值: 出现错误perror eixt

    ssize_t write(int fildes, const void *buf, size_t nbyte);
    返回值: 返回实际写出的字节数, 0表示什么也没有写

    阻塞读终端

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    // 阻塞读终端 
    int main(int argc, char const *argv[])
    {
    	char buf[10];
    	int n;
    	n = read(STDIN_FILENO, buf, 10);
    	if (n < 0) {
    		perror("read STDIN_FILENO");
    		exit(1);
    	}
    	write(STDOUT_FILENO, buf, n); 
    	return 0;
    } 
    

    非阻塞读终端

    #include <unistd.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #define MSG_TRY "try again
    "
    
    // 非阻塞读终端
    int main(int argc, char const *argv[])
    {
    	char buf[10];
    	int fd, n;
    	// /dev/tty --> 当前打开的终端设备
    	fd = open("/dev/tty", O_RDONLY | O_NONBLOCK);
    	if (fd < 0) {
    		perror("open /dev/tty");
    		exit(1);
    	}
    	tryagain:
    	n = read(fd, buf, 10);
    	if (n < 0) {
    		// 如果write为非阻塞, 但是没有数据可读, 此时全局变量errno被设置为EAGAIN
    		if (errno == EAGAIN) {
    			sleep(3);
    			write(STDOUT_FILENO, MSG_TRY, strlen(MSG_TRY));
    			goto tryagain;
    		}
    		perror("read /dev/tty");
    		exit(1);
    	}
    	write(STDOUT_FILENO, buf, n);
    	close(fd);
    
    	return 0;
    }
    

    阻塞和非阻塞是文件的属性
    默认非阻塞: 普通文件
    默认阻塞: 终端设备, 管道, 套接字

  • 相关阅读:
    最大团问题
    树的重心与相关性质
    2020年牛客算法入门课练习赛3 B
    牛客练习赛66 E
    浅谈后缀数组SA
    [随机化算法] 听天由命?浅谈Simulate Anneal模拟退火算法
    “优美的暴力”——树上启发式合并
    [线段树系列] LCT打延迟标记的正确姿势
    [Tarjan系列] Tarjan算法与有向图的SCC
    [Tarjan系列] 无向图e-DCC和v-DCC的缩点
  • 原文地址:https://www.cnblogs.com/hesper/p/10739065.html
Copyright © 2020-2023  润新知