`
coolerbaosi
  • 浏览: 725418 次
文章分类
社区版块
存档分类
最新评论

等待队列wait queue

 
阅读更多

在Linux驱动程序中,可以使用等待队列(wait queue)来实现阻塞进程的唤醒。wait queue很早就作为一种基本的功能单位出现在Linux内核里了,它以队列位基础数据结构,与进程调度机制紧密结合,能够用于实现内核中异步事件通知机制。等待队列可以用来同步对系统资源的访问。(信号量在内核中也依赖等待队列来实现)。
Linux-2.6提供如下关于等待队列的操作:

(1) 定义"等待队列头"
wait_queue_head_t my_queue;


(2) 初始化"等待队列头"
init_waitqueue_head(&my_queue);
定义和初始化的快捷方式:
DECLARE_WAIT_QUEUE_HEAD(my_queue);


(3) 定义等待队列
DECLARE_WAITQUEUE(name, tsk);
定义并初始化一个名为name的等待队列(wait_queue_t);


(4) 添加/移除等待队列
void fastcall add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
void fastcall remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
add_wait_queue()用于将等待队列wait添加到等待队列头q指向的等待队列链表中,而remove_wait_queue()用于将等待队列wait从附属的等待队列头q指向的等待队列链表中移除。


(5) 等待事件
wait_event(queue, condition);
wait_event_interruptible(queue, condition);
wait_event_timeout(queue, condition, timeout);
wait_event_interruptible_timeout(queue, condition, timeout);
等待第一个参数queue作为等待队列头的等待队列被唤醒,而且第二个参数condition必须满足,否则阻塞。wait_event()和wait_event_interruptible()的区别在于后者可以被信号打断,而前者不能。加上timeout后的宏意味着阻塞等待的超时时间,以jiffy为单位,在第三个参数的timeout到达时,不论condition是否满足,均返回。


(6) 唤醒队列
void wake_up(wait_queue_head_t *queue);
void wake_up_interruptible(wait_queue_head_t *queue);
上述操作会唤醒以queue作为等待队列头的所有等待队列对应的进程。
wake_up() <---> wait_event()
wait_event_timeout()
wake_up_interruptible() <---> wait_event_interruptible()
wait_event_interruptible_timeout()

wake_up()可以唤醒处于TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE的进程
wake_up_interruptble()只能唤醒处于TASK_INTERRUPTIBLE的进程。


(7) 在等待队列上睡眠
sleep_on(wait_queue_head_t *q);
interruptible_sleep_on(wait_queue_head_t *q);

sleep_on()函数的作用就是将当前进程的状态置成TASK_UNINTERRUPTIBLE,定义一个等待队列,并把它添加到等待队列头q,直到支援获得,q引导的等待队列被唤醒。
interruptible_sleep_on()与sleep_on()函数类似,其作用是将目前进程的状态置成TASK_INTERRUPTIBLE,并定义一个等待队列,之后把它附属到等待队列头q,直到资源可获得,q引导的等待队列被唤醒或者进程收到信号。

sleep_on() <---> wake_up()

interruptible_sleep_on() <---> wake_up_interruptible()

与(5)的区别是不需要condition参数,只有调用wake_up()或wake_up_interruptible()就唤醒队列上的所有等待


在Linux驱动程序中,可以使用等待队列(wait queue)来实现阻塞进程的唤醒。wait queue很早就作为一种基本的功能单位出现在Linux内核里了,它以队列位基础数据结构,与进程调度机制紧密结合,能够用于实现内核中异步事件通知机制。等待队列可以用来同步对系统资源的访问。(信号量在内核中也依赖等待队列来实现)。
Linux-2.6提供如下关于等待队列的操作:

(1) 定义"等待队列头"
wait_queue_head_t my_queue;


(2) 初始化"等待队列头"
init_waitqueue_head(&my_queue);
定义和初始化的快捷方式:
DECLARE_WAIT_QUEUE_HEAD(my_queue);


(3) 定义等待队列
DECLARE_WAITQUEUE(name, tsk);
定义并初始化一个名为name的等待队列(wait_queue_t);


(4) 添加/移除等待队列
void fastcall add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
void fastcall remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
add_wait_queue()用于将等待队列wait添加到等待队列头q指向的等待队列链表中,而remove_wait_queue()用于将等待队列wait从附属的等待队列头q指向的等待队列链表中移除。


(5) 等待事件
wait_event(queue, condition);
wait_event_interruptible(queue, condition);
wait_event_timeout(queue, condition, timeout);
wait_event_interruptible_timeout(queue, condition, timeout);
等待第一个参数queue作为等待队列头的等待队列被唤醒,而且第二个参数condition必须满足,否则阻塞。wait_event()和wait_event_interruptible()的区别在于后者可以被信号打断,而前者不能。加上timeout后的宏意味着阻塞等待的超时时间,以jiffy为单位,在第三个参数的timeout到达时,不论condition是否满足,均返回。


(6) 唤醒队列
void wake_up(wait_queue_head_t *queue);
void wake_up_interruptible(wait_queue_head_t *queue);
上述操作会唤醒以queue作为等待队列头的所有等待队列对应的进程。
wake_up() <---> wait_event()
wait_event_timeout()
wake_up_interruptible() <---> wait_event_interruptible()
wait_event_interruptible_timeout()

wake_up()可以唤醒处于TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE的进程
wake_up_interruptble()只能唤醒处于TASK_INTERRUPTIBLE的进程。


(7) 在等待队列上睡眠
sleep_on(wait_queue_head_t *q);
interruptible_sleep_on(wait_queue_head_t *q);

sleep_on()函数的作用就是将当前进程的状态置成TASK_UNINTERRUPTIBLE,定义一个等待队列,并把它添加到等待队列头q,直到支援获得,q引导的等待队列被唤醒。
interruptible_sleep_on()与sleep_on()函数类似,其作用是将目前进程的状态置成TASK_INTERRUPTIBLE,并定义一个等待队列,之后把它附属到等待队列头q,直到资源可获得,q引导的等待队列被唤醒或者进程收到信号。

sleep_on() <---> wake_up()

interruptible_sleep_on() <---> wake_up_interruptible()

与(5)的区别是不需要condition参数,只有调用wake_up()或wake_up_interruptible()就唤醒队列上的所有等待

分享到:
评论

相关推荐

    \Linux内核机制之等待队列

    \Linux内核机制之等待队列,消息讲述了wait_queue队列的数据结构和在内核中的实现源码,有助于对如何使用队列更加一目了然。

    java 停车厂模拟管理程序的设计与实现

    [问题描述] 设停车厂只有一个可停放几辆汽车的狭长通道,且只有—个大门可供汽车进出。汽车在停车场内按车辆到达的先后顺序依次排列,若车场内已停满几辆...4.设计等待队列WaitQueue 5.定义结点类Node 6.搭建管理界面

    fast-wait-free-queue, 并发队列实现的基准框架.zip

    fast-wait-free-queue, 并发队列实现的基准框架 快速等待空闲队列这是评估并发队列性能的基准测试框架。 目前,它包含4 个并发队列。 它们是:一个快速等待队列 wfqueueafek的Morrison和 lcrqkallimanis的Fatourou和...

    Linux操作系统内核等待队列机制介绍

    相信很多写程序的人都写过 socket 的程序。...在 kernel 里,wait_queue 的应用很广,举凡 device driver semaphore 等方面都会使用到 wait_queue 来 implement。所以,它算是 kernel 里基本的一个数据结构。

    设备驱动中阻塞与非阻塞及实现

    设备驱动中阻塞与非阻塞及实现:在Linux驱动程序中,我们可以使用等待队列(wait queue)来实现阻塞操作。wait queue很早就作为一个基本的功能单位出现在Linux内核里了,它以队列为基础数据结构,与进程调度机制紧密...

    Linux设备驱动阻塞与非阻塞

    在Linux驱动程序中,我们可以使用等待队列(wait queue)来实现阻塞操作。wait queue很早就作为一个基本的功能单位出现在Linux内核里了,它以队列为基础数据结构,与进程调度机制紧密结合,能够用于实现核心的异步...

    Python 进程操作之进程间通过队列共享数据,队列Queue简单示例

    本文实例讲述了Python 进程操作之进程间通过队列共享数据,队列Queue。分享给大家供大家参考,具体如下: 队列中的数据是放在内存中的,可以通过分布式缓存redis优化队列。 demo.py(进程通过队列共享数据): ...

    multiqueue:具有广播功能的快速mpmc队列

    MultiQueue:快速MPMC广播队列 MultiQueue是一个快速绑定的mpmc队列,它支持广播/广播样式的操作 多队列基于LMAX Disruptor的队列设计,并进行了一些改进: 它可以充当期货流/接收器,因此您可以轻松设置高性能计算...

    harmonyos2-co-queue:co的先进先出队列

    队列。 例子 创建一个队列,其中一个生产者和两个消费者做假工作: var Queue = require ( 'co-queue' ) ; var co = require ( 'co' ) ; var wait = require ( 'co-wait' ) ; var queue = new Queue ; co ( function...

    python 队列详解及实例代码

    其中,Empty和Full是两个异常类,当队列的Queue.get(block=0)或者调用get_nowait()时,如果队列为空,则抛EmptyException异常。  同理,当队列的Queue.put(block=0)或者调用put_nowait()时,如果队列为达到maxsize...

    gitlab-ci-pipeline-queue:gitlab ci的简单管道队列工具

    这并不是完全理想的,因为它将使用运行器实例来等待和轮询gitlab的API。 需要您自担风险使用它。 使用它 创建一个api 并将其作为名为GITLAB_API_TOKEN的提供 在您的.gitlab-cy.yml文件中,添加以下阶段和作业: ...

    python 多线程的同步机制 以python2例程的方式讲解了python 多线程的同步 常用的方法,主要是锁、条件同步、队列

     队列:Queue  首先一个线程成功获得一个条件变量后,调用此条件变量的wait()方法会导致这个线程释放这个锁,并进入“blocked”状态,直到另一个线程调用同一个条件变量的notify()方法来唤醒那个进入“blocked...

    GrandSwiftDispatch:不那么盛大,不那么Swift,也不那么快

    主队列可通过Queue.Main访问 当前队列可通过Queue.Current访问 每个服务质量都有一个共享队列: 通过Queue.Interactive用户交互操作 用户通过Queue.User发起的操作 通过Queue.Utility实用程序操作 通过Queue....

    操作系统进程调度算法.pptx

    简单进程执行速度快 缺点:无法准确预估运行时间,容易造成长进程饥饿 短作业优先算法就是在 FCFS 算法中加入对 waitQueue 等待队列按照运行时间排序 操作系统进程调度算法全文共13页,当前为第4页。 为 CPU 的执行...

    DiskQueue:适用于.Net和Mono的线程安全,多进程(ish)持久队列库

    PersistentQueue.WaitFor(...)是主要入口点。 这将尝试在给定的存储位置上获得排他锁。 首次使用时,将创建一个目录,其中包含必需的文件。 可以在线程之间共享此队列对象。 每个线程应调用OpenSession()以获得自己...

    Python进程间通信Queue实例解析

    本文研究的主要是Python进程间通信Queue的相关实例,具体如下。... Queue.get_nowait():相当Queue.get(False),取不到值时触发异常:Empty; Queue.put():将一个值添加进数列,可传参超时时长。 Queue

    laravel-queue-debouncer:非常容易对Laravel队列作业进行反跳

    composer require mpbarlow/laravel-queue-debouncer 背景 该软件包允许对Laravel应用程序中的任何队列作业或链进行去抖动,这意味着无论在指定的超时窗口内将其调度多少次,它都只会运行一次。 例如,假设您在...

    async-blocking-queue:AsyncBlockingQueue

    异步阻塞队列npm install --save async-blocking-queueAsyncBlockingQueue import AsyncBlockingQueue from 'async-blocking-queue' ;var queue = new AsyncBlockingQueue ( ) ;// wait for next enqueue() ...

    医务室模拟_vc/类/多线程

    帮朋友写的,用VC++模拟实现,本来想完全用类实现,但要求中要用队列,所以加上了队列结构。使用2个线程模拟医生处理病人事件和病人到达诊所事件。因看了论坛原来的资源需要2分,觉得自己的比那个花的工夫多,而且也更...

    银行业务排队模拟系统

    首先从题目分析:N个窗口排队,首先就要建立N个队列来存储排队的用户信息 ,然后算出那个队列最短就用户就到那个队伍排队,同时通过随机生成他办理业务的时间和到来的时间,通过计算用户的到来时间和离开时间就可以...

Global site tag (gtag.js) - Google Analytics