linux驱动程序开发4

驱动程序中的阻塞与非阻塞编程

一个驱动当它无法立刻满足请求的时候,驱动应当阻塞进程,使它进入休眠,直到请求可以继续时再将它唤醒。

操作系统实现的原理是,当驱动发现无法满足进程的请求时,会调用内核api将该进程挂入等待队列后主动放弃cpu,从而进程睡眠,当驱动发现已睡眠进程被唤醒的条件已经满足时,将会唤醒睡眠进程,其实质是调用内核api将挂入等待队列的进程从等待队列中摘除,然后调用该进程运行。


使用方法:

1 定义及初始化

静态方式:DECLARE_WAIT_QUEUE_HEAD(name);

动态方式:wait_queue_head_t my_queue;

                  init_waitqueue_head(&my_queue);

2 睡眠函数,当驱动无法满足用户进程时调用

wait_event(queue, condition);

wait_event_interruptible(queue, condition);

wait_event_timeout(queue, condition, timeout);

3 唤醒函数,当驱动发现可以满足睡眠用户进程的请求时,调用来唤醒睡眠进程

wake_up(wait_queue_head_t *queue);

wake_up_interruptible(wait_queue_head_t *queue)


手动进行睡眠的过程:

1 分配wait queue entry wait_queue_t并用自身current初始化

DEFINE_WAIT(wait);

2 将wait queue entry链入等待队列,同时设置进程状态

void prepare_to_wait(wait_queue_head_t *queue,
wait_queue_t *wait,
int state);

prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE);

3 放弃cpu

schedule();

4 被唤醒后,设置进程标志为运行,从等待队列中摘除等待结构体

void finish_wait(wait_queue_head_t *queue, wait_queue_t *wait);

finish_wait(&dev->outq, &wait);


非阻塞IO的操作方法

如果一个进程调用read,但是没有数据可以读,这个read应立即返回而不是阻塞,返回-EAGAIN表示需要再次读取

非阻塞IO由filp->f_flags中的O_NONBLOCK标志来指示,驱动程序中只需要判断这个标志,返回EAGAIN即可,这个标志是在打开文件的时候传入的

fd=open("./scullp0", O_RDWR|O_NONBLOCK);


猜你喜欢

转载自blog.csdn.net/oushaojun2/article/details/64439881