阻塞与非阻塞

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了阻塞与非阻塞相关的知识,希望对你有一定的参考价值。

阻塞是指执行设备操作时,不能获得 资源,则挂起进程直到满足可操作的条件在进行操作。

非阻塞是在进程不能进行设备操作时,并不挂起,要么放弃、要么不停的查询,直到进行操作为止。

等待队列;

typedef struct _wait_queue_head  wait_queue_head_t;

1.定义等待队列头部:wait_queue_head_t my_head;

2.初始化等待队列头:init_waitqueue_head(&my_queue);

DECLARE_WAIT_QUEUE_HEAD(name)可以作为 定义并初始化等待队列头的“快捷方式”。

3.定义等待队列元素:

DECLARE_WAITQUEUE(name,tsk);

4,添加和移除等待队列

void add_wait_queue(wait_queue_head_t *q, wiat_queue_t *wait);

void remove_wait_queue(wait_queue_head_t *q, wiat_queue_t *wait);

add_wait_queue()用于将等待队列元素wait添加到等待队列的头部q指向的双向链表中,

void remove_wait_queue用于将等待队列元素wait从等待队列的头部q指向的双向链表移除。

5.等待事件

wait_event(queue,condition)

wait_event_interruptible(queue,condition);

等待参数queue作为等待队列头部的队列被唤醒,condition必须满足,否则继续阻塞。

6.唤醒队列

void wake_up(wait_queue_head_t *queue);

void wake_up_interruptible(wait_queue_head_t *queue);

要对应起来用。

 

7,在等待队列上的睡眠

sleep_on(wait_queue_head_t *queue);

interruptible_sleep_on(wait_queue_head_t *queue);

sleep_on()函数的作用将进程状态置成task_uninterruptible,定义一个等待队列元素。之后把它赋予到q指向的队列,直到资源获得。

interruptible_sleep_on()函数的作用将进程状态置成task_interruptible。

 

Linux进程状态

1.如果非阻塞访问(o_nonblock)设备忙时,直接返回“-EAGAIN”

2.对于阻塞访问,会调用_set_current_state(task_interruptible)进行进程的状态切换并显示通过"schedule()"调度其他进程的执行

3.醒来的时候注意,由于调度出去的时候,进程状态task_interruptible,即浅度睡眠,唤醒的可能是信号,通过signal_pending(current)了解是不是信号,是返回“erestartsys”

轮询

int select(int numfd,fd_set *readfds, fd_set *writefds,fd_set *exceptfds,struct timeval *timeout);

其中readfds ,writefds,expectfds分别是select()监视的读写和异常处理 的文件描述符集合。

 

poll函数原型

unsigned int (*poll)(struct file * filp, struct poll_table* wait);

1.对可能引起设备文件变化状态的等待队列调用poll_wait(),将对应的等待队列头部添加到poll_table

2.返回表示是否对设备进行无阻塞读,写访问的掩码。

void poll_wait(struct file *filp,wait_queue_head_t *queue,poll_table *wait)

 poll_wait就是把当前进程添加到wait参数指定的等待列表,实际让唤醒参数queue对应的等待队列可以唤醒因select()而睡眠的进程。

以上是关于阻塞与非阻塞的主要内容,如果未能解决你的问题,请参考以下文章

阻塞赋值与非阻塞赋值(转载)

Linux 阻塞与非阻塞串行读取

socket的阻塞与非阻塞,同步与非同步

《linux设备驱动开发详解》笔记——8阻塞与非阻塞IO

阻塞与非阻塞异步代码

聊聊同步异步阻塞与非阻塞