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\n"

// 非阻塞读终端
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;
}

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

posted @ 2019-04-19 21:51  张飘扬  阅读(4008)  评论(0编辑  收藏  举报