Linux 阻塞和非阻塞IO

Linux 阻塞和非阻塞IO

阻塞IO

当应用程序对设备驱动进行操作的时候,如果不能获取到设备资源,那么阻塞式IO就会将应用程序对应的线程挂起,直到设备资源可以获取为止。
应用程序调用read函数从设备中读取数据,当设备不可用或数据未准备好的时候就会进入到休眠态。等设备可用的时候就会从休眠态唤醒,然后从设备中读取数据返回给应用程序。

int fd; 
int data = 0; 

fd = open("/dev/xxx_dev", O_RDWR); /* 阻塞方式打开 */
ret = read(fd, &data, sizeof(data)); /* 读取数据 */

非阻塞IO

对于非阻塞IO,应用程序对应的线程不会挂起,它会一直轮询等待,直到设备资源可以使用,要么就直接放弃。
应用程序使用非阻塞访问方式从设备读取数据,当设备不可用或数据未准备好的时候会立即向内核返回一个错误码,表示数据读取失败。应用程序会再次读取数据,这样一直往复循环,直到数据读取成功。

int fd; 
int data = 0; 

fd = open("/dev/xxx_dev", O_RDWR | O_NONBLOCK); /* 非阻塞方式打开 */
ret = read(fd, &data, sizeof(data)); /* 读取数据 */

阻塞IO和等待队列

阻塞访问最大的好处就是当设备文件不可操作的时候进程可以进入休眠态,这样可以将CPU资源让出来。但是,当设备文件可以操作的时候必须唤醒进程,一般在中断函数里面完成唤醒工作。
Linux内核提供了等待队列(wait queue)来实现阻塞进程的唤醒工作,如果我们要在驱动中使用等待队列,必须创建并初始化一个等待队列头(wait_queue_head_t)。
等待队列头:等待队列的头部
等待队列项:每个访问设备的进程都是一个队列项
//初始化等待队列头
void init_waitqueue_head(wait_queue_head_t *q)
//初始化一个等待队列项 
DECLARE_WAITQUEUE(name, tsk)
//将队列项添加到等待队列头 
void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
//将队列项从等待队列头移除 
void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
//等待唤醒
void wake_up(wait_queue_head_t *q)
void wake_up_interruptible(wait_queue_head_t *q)
//等待事件
wait_event(wq, condition)
wait_event_timeout(wq, condition, timeout)
wait_event_interruptible(wq, condition)
wait_event_interruptible_timeout(wq, condition, timeout)

非阻塞IO和poll机制

poll,epoll,select可以用于处理轮询。

//select函数
int select(int nfds, 
	fd_set *readfds, 
	fd_set *writefds,
	fd_set *exceptfds, 
	struct timeval *timeout)
//poll函数
int poll(struct pollfd *fds, 
	nfds_t nfds, 
	int timeout)
//epoll函数
int epoll_create(int size)

int epoll_ctl(int epfd, 
	int op, 
	int fd,
	struct epoll_event *event)
	 
struct epoll_event {
	uint32_t events; /* epoll 事件 */
	epoll_data_t data; /* 用户数据 */
};

int epoll_wait(int epfd, 
	struct epoll_event *events,
	int maxevents, 
	int timeout)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Paper_Love

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值