我们已经见到当一个进程调用 wake_up 在等待队列上, 所有的在这个队列上等待的进程 被置为可运行的. 在许多情况下, 这是正确的做法. 但是, 在别的情况下, 可能提前知道 只有一个被唤醒的进程将成功获得需要的资源, 并且其余的将简单地再次睡眠. 每个这样 的进程, 但是, 必须获得处理器, 竞争资源(和任何的管理用的锁), 并且明确地回到睡眠. 如果在等待队列中的进程数目大, 这个"惊群"行为可能严重降低系统的性能.

为应对实际世界中的惊群问题, 内核开发者增加了一个"互斥等待"选项到内核中. 一个互 斥等待的行为非常象一个正常的睡眠, 有 2 个重要的不同:

  • 当一个等待队列入口有 WQ_FLAG_EXCLUSEVE 标志置位, 它被添加到等待队列的尾 部. 没有这个标志的入口项, 相反, 添加到开始.
  • 当 wake_up 被在一个等待队列上调用, 它在唤醒第一个有 WQ_FLAG_EXCLUSIVE 标 志的进程后停止.

最后的结果是进行互斥等待的进程被一次唤醒一个, 以顺序的方式, 并且没有引起惊群问 题. 但内核仍然每次唤醒所有的非互斥等待者.

在驱动中采用互斥等待是要考虑的, 如果满足 2 个条件: 你希望对资源的有效竞争, 并 且唤醒一个进程就足够来完全消耗资源当资源可用时. 互斥等待对 Apacheweb 服务器工 作地很好, 例如; 当一个新连接进入, 确实地系统中的一个 Apache 进程应当被唤醒来处 理它. 我们在 scullpipe 驱动中不使用互斥等待, 但是; 很少见到竞争数据的读者(或者 竞争缓冲空间的写者), 并且我们无法知道一个读者, 一旦被唤醒, 将消耗所有的可用数 据.

使一个进程进入可中断的等待, 是调用 prepare_to_wait_exclusive 的简单事情:

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

这个调用, 当用来代替 prepare_to_wait, 设置"互斥"标志在等待队列入口项并且添加这 个进程到等待队列的尾部. 注意没有办法使用 wait_event 和它的变体来进行互斥等待.

linux进程互斥等待的更多相关文章

  1. Linux之进程的等待与其内核实现解析

    进程通过fork产生子进程,进程也会死亡,进程退出的时候将会进行内核清理,释放所有进程的资源,资源包括:内存资源,文件资源,信号量资源,共享内存资源,或者引用计数减一,或者彻底释放.     不过进程 ...

  2. Linux进程通信 之 信号灯(semphore)(System V && POSIX)

    一. 信号灯简介 信号灯与其他进程间通信方式不大相同,它主要提供对进程间共享资源访问控制机制. 相当于内存中的标志,进程可以根据它判定是否能够访问某些共享资源,同时,进程 也可以修改该标志.除了用于访 ...

  3. Linux进程通信学习总结

    http://blog.csdn.net/xiaoweibeibei/article/details/6552498 SYSV子系统的相关概念   引用标识符:引用标识符是一个整数,表示每一个SYSV ...

  4. Linux用户抢占和内核抢占详解(概念, 实现和触发时机)--Linux进程的管理与调度(二十)

    1 非抢占式和可抢占式内核 为了简化问题,我使用嵌入式实时系统uC/OS作为例子 首先要指出的是,uC/OS只有内核态,没有用户态,这和Linux不一样 多任务系统中, 内核负责管理各个任务, 或者说 ...

  5. Linux进程管理 (2)CFS调度器

    关键词: 目录: Linux进程管理 (1)进程的诞生 Linux进程管理 (2)CFS调度器 Linux进程管理 (3)SMP负载均衡 Linux进程管理 (4)HMP调度器 Linux进程管理 ( ...

  6. Linux进程描述符task_struct结构体详解--Linux进程的管理与调度(一)【转】

    Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程,这个结构体包含了一个进程所需的所有信息.它定义在include/linux/sched.h文件中. 谈到task_str ...

  7. 使用 ps、strace、lsof 进行 Linux 进程 trouble-shooting

      linux_observability_tools 介绍 在Linux 下进行进程的排错,有很多方法.比如,修改源代码,print出一些关键的信息,如果代码是Python 的话,可以使用trace ...

  8. 《Linux 性能及调优指南》1.1 Linux进程管理

    https://blog.csdn.net/ljianhui/article/details/46718835 本文为IBM RedBook的Linux Performanceand Tuning G ...

  9. linux进程的管道通信

    linux进程的管道通信 要求 编程实现进程的管道通信,掌握管道通信的同步和互斥机制. 相关函数 pipe管道 指用于连接一个读进程和一个写进程以实现他们之间通信的一个共享文件,又名pipe文件.向管 ...

随机推荐

  1. 【JZOJ4921】【NOIP2017提高组模拟12.10】幻魔皇

    题目描述 幻魔皇拉比艾尔很喜欢斐波那契树,他想找到神奇的节点对. 所谓斐波那契树,根是一个白色节点,每个白色节点都有一个黑色节点儿子,而每个黑色节点则有一个白色和一个黑色节点儿子.神奇的节点对则是指白 ...

  2. linux 下安装编译配置 QT

    注: 1,自己 make qt-everywhere-opensource-src s时,在./configure前主动装好以下3个 sudo apt-get install libX11-dev l ...

  3. python 正则表达式语法

  4. More Effective C++: 06杂项讨论

    32:在未来时态下发展程序 世事永远在变,好的软件对于变化有良好的适应能力:可以容纳新的性质,可以移植到新的平台,可以适应新的需求,可以掌握新的输入.所谓在未来时态下设计程序,就是接受“事情总会改变” ...

  5. Length of Last Word输出最后单词的字母个数

    Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the l ...

  6. mysql 使用concat模糊查询

    如果这三个字段中有值为NULL,则返回的也是NULL,那么这一条记录可能就会被错过,使用IFNULL进行判断 SELECT * FROM `magazine` WHERE CONCAT(IFNULL( ...

  7. 利用IDEA构建springboot应用-配置文件

    application.properties配置文件(不建议采用这种配置) 配置文件采用:application.yml文件会更简便,要带空格 属性配置与类中取值 添加bean属性配置到一个类里面,采 ...

  8. 二分查找 Day08

    package com.sxt.arraytest2; /* * 二分查找 前提:有序 */ public class TestBinarySearch { public static void ma ...

  9. vue init定制团队模板使用方法

    每次做项目都要自己搭建项目目录,或者换了公司就的重新搭建项目目录,是不是很麻烦呢?有没有想过一次性把项目目录搭建好,以后直接用呢?你首先想到的可能是复制自己原来的项目,然后删除.修改等等.然而有个更方 ...

  10. 在SpringBoot中使用JWT

    JWT简介 简介 JSON Web token简称JWT, 是用于对应用程序上的用户进行身份验证的标记.也就是说, 使用 JWTS 的应用程序不再需要保存有关其用户的 cookie 或其他sessio ...