Linux 高级进程管理

2023-11-09

1. 让出处理器

  Linux提供一个系统调用运行进程主动让出执行权:sched_yield。进程运行的好好的,为什么需要这个函数呢?有一种情况是用户空间线程的锁定。如果一个线程试图取得另一个线程所持有的锁,则新的线程应该让出处理器知道该锁变为可用。用户空间锁没有内核的支持,这是一个最间单、最有效率的做法。但是现在Linux线程实现引入一个使用futexes的优化解决方案。

  另一个情况是在有处理器密集型程序可用周期性调用sched_yield,试图将该进程对系统的冲击减到最小。不管怎么说,如何调度程序应该是系统的事情,而不是进程自己去管。eg:

int main(){
    int ret, i;
    ret = sched_yield();
    if(ret == -1){
    printf("调用sched_yield失败!\n");
    }
    return 0;
}

  那该调用内核是如何实现的?2.6以前的版本sched_yield所造成的影响非常小,如果存在另一个可以运行的进程,内核就切换到该进程,把进行调用的进程放在可运行进程列表的结尾处。短期内内核会对该进程进行重新调度。这样的话可能出现“乒乓球”现象,也就是两个程序来回运行,直到他们都运行结束。2.6版本中做了一些改变:

    1.如果进程是RR,把它放到可运行进程结尾,返回。
    2.否则,把它从可运行进程列表移除,放到到期进程列表,这样在其他可运行进程时间片用完之前不会再运行该进程。
    3.从可执行进程列表中找到另一个要执行的进程。

2.进程的优先级

  看过CFS中会看到进程的nice value会决定进程会运行多长时间,或者说是占用的百分比。可以通过系统调用nice来设置、获取进程的nice value。该值的范围是-20~19,越低的值越高的优先级(这个在计算虚拟时间的时候放在分母上),实时进程应该是负数,eg:

int main(){
    int ret, i;
    ret = nice(0);
    printf("当前进程的nice value:%d\n", ret);
    ret = nice(10);
    printf("当前进程的nice value:%d\n", ret);
    return 0;
}


  因为ret本来就可以是-1,那么在判断是否系统调用失败的时候就要综合ret和errno。还有两个系统调用可以更灵活地设置,getpriority可以获得进程组、用户的任何进程中优先级最高的。setpriority将所指定的所有进程优先级设置为prio,eg:

int main(){
    int ret, i;
    ret = getpriority(PRIO_PROCESS, 0);
    printf("nice value:%d\n", ret);
    ret = setpriority(PRIO_PROCESS, 0, 10);
    ret = getpriority(PRIO_PROCESS, 0);
    printf("nice value:%d\n", ret);
    return 0;
}


   进程有在处理器上执行的优先级,也有传输数据的优先级:I/O优先级。linux有额外的两个系统调用可用显示设置和取得I/O nice value,但是尚未导出:

       int ioprio_get(int which, int who);
       int ioprio_set(int which, int who, int ioprio);

3、处理器亲和性

  Linux支持具有多个处理器的单一系统。在SMP上,系统要决定每个处理器上要运行那些程序,这里有两项挑战:

      1.调度程序必须想办法充分利用所有的处理器。
      2.切换程序运行的处理器是需要代价的。
    进程会继承父进程的处理器亲和性,Linux提供两个系统调用用于获取和设定“硬亲和性”。eg:

int main(){
    int ret, i;
    cpu_set_t set;

    CPU_ZERO(&set);
    ret = sched_getaffinity(0, sizeof(cpu_set_t), &set);
    if(ret == -1)
    printf("调用失败!\n");
    for(i = 0; i < 10; i++){
    int cpu = CPU_ISSET(i, &set);
    printf("cpu=%i is %s\n", i, cpu?"set":"unset");
    }

    CPU_ZERO(&set);
    CPU_SET(0, &set);
    CPU_CLR(1, &set);
    ret = sched_setaffinity(0, sizeof(cpu_set_t), &set);
    if(ret == -1)
    printf("调用失败!\n");
    for(i = 0; i < 10; i++){
    int cpu = CPU_ISSET(i, &set);
    printf("cpu=%i is %s\n", i, cpu?"set":"unset");
    }
    return 0;
}


4、Linux的调度策略与优先级

  关于Linux系统中对进程的几种调度方法和他们的区别就不在这里说了,这里关注的是如何获取、设置这些值。可以使用sched_getscheduler来获取进程的调度策略,eg:

int main(){
    int ret, i;
    struct sched_param sp;
    sp.sched_priority = 1;
    ret = sched_setscheduler(0, SCHED_RR, &sp);
    if(ret == -1)
    printf("sched_setscheduler failed.\n");
    if(errno == EPERM)
    printf("Process don't the ability.\n");

    ret = sched_getscheduler(0);
    switch(ret){
    case SCHED_OTHER:
    printf("Policy is normal.\n");
    break;
    case SCHED_RR:
    printf("Policy is round-robin.\n");
    break;
    case SCHED_FIFO:
    printf("Policy is first-in, first-out.\n");
    break;
    case -1:
    printf("sched_getscheduler failed.\n");
    break;
    default:
    printf("Unknow policy\n");
    }
    return 0;
}


       sched_getparam和sched_setparam接口可用于取得、设定一个已经设定好的策略,这里不只是返回一个策略的ID,eg:

int main(){
    int ret, i;
    struct sched_param sp;

    sp.sched_priority = 1;
    ret = sched_setparam(0, &sp);    
    if(ret == -1)
    printf("sched_setparam error.\n");

    ret = sched_getparam(0, &sp);
    if(ret == -1)
    printf("sched_getparam error.\n");

    printf("our priority is %d.\n", sp.sched_priority);
    return 0;
}


      Linux提供两个用于取得有效优先值的范围的系统调用,分别返回最大值、最小值,eg:

int main(){
    int ret, i;
    struct sched_param sp;

    ret = sched_get_priority_min(SCHED_RR);
    if(ret == -1)
    printf("sched_get_priority_min error.\n");
    printf("The min nice value is %d.\n", ret);

    ret = sched_get_priority_max(SCHED_RR);
    if(ret == -1)
    printf("sched_get_priority_max error.\n");
    printf("The mmax nice value is %d.\n", ret);
    return 0;
}


       关于时间片,这个概念可能在Linux中和传统的在操作系统的课程中学到的还是有很大的区别的,如果感兴趣的化可以看看CFS里面的。通过sched_rr_get_interval可以取到分配给pid的时间片的长度,eg:

int main(){
    int ret, i;
    struct timespec tp;
    ret = sched_rr_get_interval(0, &tp);
    if(ret == -1)
    printf("sched_rr_get_interval error.\n");
    printf("The time is %ds:%ldns.\n", (int)tp.tv_sec, tp.tv_nsec);
    return 0;
}


5、实时进程的预防措施


  由于实时进程的本质,开发者在开发和调试此类程序时应该谨慎行事,如果一个实时进程突然发脾气,系统的反应会突然变慢。任何一个CPU密集型循环在一个实时程序中会继续无止境地运行下去,只要没有优先级更高实时进程变成可运行的。因此设计实时程序的时候要谨慎,这类程序至高无上,可用轻易托跨整个系统,下面是一些要决与注意事项:

     1.因为实时进程会好用系统上一切资源,小心不要让系统其他进程等不到处理时间。
     2.循环可能会一直运行到结束。
     3.小心忙碌等待,也就是实时进程等待一个优先级低的进程所占有的资源。
     4.开发一个实时进程的时候,让一个终端保持开启状态,以更高的优先级来运行该实时进程,发生紧急情况终端机依然会有反应,允许你终止失控的实时进程。
     5.使用chrt设置、取得实时属性。
     6.资源限制

 Linux对进程加上了若干资源限制,这些限制是一个进程所能耗用的内核资源的上限。限制的类型如下:

    1.RLIMIT_AS:地址空间上限。
    2.RLIMIT_CORE:core文件大小上限。
    3.RLIMIT_CPU:可耗用CPU时间上限。
    4.RLIMIT_DATA:数据段与堆的上限。
    5.RLIMIT_FSIZE:所能创建文件的大小上限。
    6.RLIMIT_LOCKS:文件锁数目上限。
    7.RLIMIT_MEMLOCK:不具备CAP_SYS_IPC能力的进程最多将多少个字节锁进内存。
    8.RLIMIT_MSGQUEUE:可以在消息队列中分配多少字节。
    9.RLIMIT_NICE:最多可以将自己的友善值调多低。
   10.RLIMIT_NOFILE:文件描述符数目的上限。
   11.RLIMIT_NPROC:用户在系统上能运行进程数目上限。
   12.RLIMIT_RSS:内存中页面的数目的上线。
   13.RLIMIT_RTPRIO:不具备CAP_SYS_NICE能力进程所能请求的实时优先级的上限。
   14.RLIMIT_SIGPENDING:在队列中信号量的上限,Linux特有的限制。
   15.RLIMIT_STACK:堆栈大小的上限。
    这些就不多说了,到了实际用到的时候再仔细看,eg:

 

int main(){
    int ret, i;
    struct rlimit rlim;

    rlim.rlim_cur = 32*1024*1024;
    rlim.rlim_max = RLIM_INFINITY;
    ret = setrlimit(RLIMIT_CORE, &rlim);

    ret = getrlimit(RLIMIT_CORE, &rlim);
    if(ret == -1)
    printf("getrlimit error.\n");
    printf("RLIMIT_CORE limits: soft=%ld hard=%ld\n", rlim.rlim_cur, rlim.rlim_max);

    return 0;
}


 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux 高级进程管理 的相关文章

  • 面试题创作0009,请问Linux kernel中的spinlock_t 是如何实现互斥访问同一数据的?

    面试题创作0007 请问Linux kernel中的spinlock t 是如何实现互斥访问同一数据的 在单核多线程 多核多线程 多cpu多线程中 spinlock t实现互斥的机制有区别么 分别是什么呢 进一步列举一些使用spinlock
  • 内核调试方法 三

    目录 大海里的鱼有很多 而我们需要的是鱼钩一只 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级调试 第一部分 基础知识 总纲 内核世界的陷阱 源码阅读的陷阱 代码调试的陷阱 原理理解的陷阱 建立调试环境 发行版的选择和
  • linux内存管理(十四)-内存OOM触发分析

    在内存分配路径上 当内存不足的时候会触发kswapd 或者内存规整 极端情况会触发OOM 来获取更多内存 在内存回收失败之后 会进行OOM OOM的入口是 alloc pages may oom 文件位于mm page alloc c中 s
  • 面试题创作0008,请说明当系统中的主CPU的MMU单元,与设备中的MMU单元共用内存时,两个CPU地址总线与内存的链接方式。

    请说明当系统中的主CPU的MMU单元 与设备中的MMU单元共用内存时 两个CPU地址总线与内存的链接方式 这对软件编程的影响是什么呢 比如如何做到互知内存的分配情况 避免两个CPU打架的机制
  • Linux 下系统调用的三种方法

    系统调用 System Call 是操作系统为在用户态运行的进程与硬件设备 如CPU 磁盘 打印机等 进行交互提供的一组接口 当用户进程需要发生系统调用时 CPU 通过软中断切换到内核态开始执行内核系统调用函数 下面介绍Linux 下三种发
  • Linux内核:配置内核(一)

    本文译自Linux orgDevynCJohnson的系列文章 Linux内核 本篇链接 http www linux org threads the linux kernel configuring the kernel part 1 4
  • linux内核中GPIO的使用(一)--IO内存

    一 相关概念 使用IO内存将物理地址映射为虚拟地址 再通过对虚拟地址的操作来控制硬件 所谓的IO内存是指一种编址方式 不同cpu平台使用的编址方式不同 一种是 IO内存 方式 也叫统一编址方式 是指内存和外设的地址是在同一个地址空间上的 如
  • 新手玩转Linux Kernel漏洞之Null Pointer Dereference

    新手玩转Linux Kernel漏洞之Null Pointer Dereference 前言 这是我内核漏洞的入门篇 不是很复杂 希望能给徘徊在门外的小伙伴一点启发 漏洞描述 A NULL pointer dereference occur
  • linux boot 查看module信息

    1 查看内置模块信息 lib modules uname r modules builtin 如 cat lib modules linux4 15 0 modules builtin 或者grep y boot config 4 15 0
  • OOM Killer 持续更新中

    虚拟地址空间的概念都门儿清 Linux 认为用户进程调用malloc申请了动态内存后不见得马上就会使用这段内存进行写读操作 Linux使用了拖到最后的分配机制 用时分配机制 但是 即使是用时分配 也不见得总有内存可分配 当进程太多 显得内存
  • Linux Kernel:syscall之fork与exec

    目录 环境 一 前言 二 进程复制 1 写时复制 2 系统调用 3 kernel c
  • Linux 网络协议栈开发(二)—— 二层桥转发基础

    做为网络设备 二层转发是最基本的功能 要想继续学习linux 内核协议栈 必须明白二层转发的流程 这篇文章举例讲一讲二层转发的流程 二层转发是根据报文的目的MAC直接进行转发 转发过程中不用对报文的头部做任何的修改 三层转发是根据报文的ip
  • Linux 高级进程管理

    1 让出处理器 Linux提供一个系统调用运行进程主动让出执行权 sched yield 进程运行的好好的 为什么需要这个函数呢 有一种情况是用户空间线程的锁定 如果一个线程试图取得另一个线程所持有的锁 则新的线程应该让出处理器知道该锁变为
  • linux源代码.tar.xz解压

    刚开始学习linux内核 在linux内核官网https www kernel org 下载 我下载的版本是 linux 2 6 34 14 tar xz 由于我的linux中没有安装 xz的解压缩软件 需要下载 http download
  • 【buildroot】buildroot使用总结

    文章目录 一 buildroot使用步骤 1 构建图形配置界面 2 配置Target options 3 配置Build options 4 配置Toolchain 5 配置 System configuration 6 配置 Filesy
  • 【linux kernel】linux中断管理—软中断

    linux中断管理 软中断 一 简介 软中断是linux预留给系统中对时间要求最为严苛和最重要的中断下半部使用的 并且 驱动中只有一些对时间极其敏感的模块使用了 例如 块设备和网络子系统 linux系统中定义了几种软中断类型 如下所示 in
  • Android中Log信息的输出方法

    共两篇文章 第一篇讲述了如何在程序中输出Log信息 第二篇详细的分析了Log信息的输出机制 下面是第一篇 转自 http blog 163 com binghaitao 126 blog static 3383532520099309366
  • sel4白皮书翻译

    首发地址 http trialley top pages 53ac44 CSDN地址 https blog csdn net lgfx21 article details 117606097 翻译与转发许可 作者 Gernot Heiser
  • SELinux深入理解

    1 简介 SELinux带给Linux的主要价值是 提供了一个灵活的 可配置的MAC机制 Security Enhanced Linux SELinux 由以下两部分组成 1 Kernel SELinux模块 kernel security
  • Linux内核之pid为0和pid为1【转】

    转自 https blog csdn net jingyilin2008 article details 7815508 ops request misc 257B 2522request 255Fid 2522 253A 25221592

随机推荐

  • INCA二次开发-MIP

    1 INCA介绍 INCA是常用的汽车ECU测试和标定的 广泛应用于动力总成等领域 INCA提供了丰富的接口 供用户自动化 定制化 本公众号通过几篇文章 介绍下一些二次开发的方法 本篇介绍MIP 2 MIP MIP MATLABIntegr
  • 【cdk的使用】C 最精简的线程池使用 源码只有100行

    Github地址 https github com wujin1989 cdk 首先cdk的线程池实现只用了100行左右代码 非常精简 有兴趣的可以阅读一下 中规中矩 只要项目对线程池性能要求不是非常的苛刻 我觉得100行的线程池足矣 但是
  • Hyperledger Fabric和Composer实现区块链应用程序

    目前无法绕过技术领域的是区块链话题 但除了加密货币之外 还有更多有趣的应用程序可以带来许多激动人心的软件生态系统 这也适用于Hyperledger项目 该项目提供了一个非常模块化的区块链框架 让我们看看使用Hyperledger Fabri
  • text-align=center 失效原因

    text align属性是针对 内联元素居中得属性设置 对于块状元素使用margin 0 auto 来控制居中 笔者在设置一个h2标签时设置了text align center 但是却始终出现在中间偏左得位置 第一反应是可能样式冲突了 但是
  • [转]小功能⭐️Unity获取点击到的UI

    文章目录 Unity获取点击到的UI物体 修改Button颜色 Button为Sprite模式下 修改不同状态图片 Unity获取点击到的UI物体 将下面方法写在Button的点击事件里 即可传出当前button所依赖物体的名称 var o
  • ARP协议的漏洞、作用、危害以及防御

    首先 ARP协议工作在网络层 ARP是Address Resolution Protocol的缩写 中文名 地址 解析 协议 作用 已知对方的IP地址 获取对方的MAC地址 原理 过程 1 发送ARP广播请求 2 回应ARP单播应答 arp
  • 【Qt-15】Qt与C++数据类型之间的转换

    1 String与QString之间的转换 string2QString string out weight QString qstr qstr QString fromStdString out weight QString2String
  • 搞一个release版本的aar包

    最近在做一个aar包给第三方使用 由于是第一次做这个aar包 在所有的功能代码完成需要打包的时候发现 坑开始出现了 于是各种百度 开始吧 首先你需要创建一个Android项目 然后创建一个android的library 下一步 剩下的就看你
  • JavaWeb.MVC购物车(第一部分)

    前言 这一篇我会使用servlet EL JSTL 三层架构写一个简单的购物车项目 内容比较多 这只是第一部分 只有登陆 首页数据显示和商品添加到购物车的功能 还有一部分功能的代码我会写在下一篇博客里 感兴趣的朋友们可以看一看 也希望大家可
  • Blender2.9基础七:外部插件篇

    一 插件安装 1 安装插件 2 插件显示位置 二 材质贴图相关插件 1 GrabDoc 贴图烘培插件 GrabDoc可以运行一键式场景设置 然后开始建模 对形状进行建模后 甚至在建模阶段 你可以实时预览材质在视口中的外观 主要特点 实时材质
  • unity3D 脚本中按键或鼠标输入响应函数

    简单地总结一下 unity中脚本实现输入 键盘和鼠标 的响应事件函数 不够完善 以后碰到再慢慢添加 键盘输入 1 Input GetKey up 按住键盘上键 2 Input GetKey KeyCode UpArrow 按住键盘上键 Ke
  • JS实现将数组中某个属性值相同的元素,放在一起

    function sortArr arrList str var arr 大数组 t 临时属性值相同数组 临时的变量 tmp if arrList length gt 0 tmp arrList 0 str 将相同类别的对象添加到同一个数组
  • [从零开始学习FPGA编程-44]:视野篇 - 集成电路助力数字化时代高质量发展-1-集成电路芯片主要形态

    目录 前言背景 什么是集成电路 什么是数字化时代
  • 为什么小程序预览时必须打开‘调试工具vconsole’才能正常运行?

    这是因为没有为小程序配置域名导致的 预览或者使用小程序体验版的时候 小程序会自动校验你是否配置了合法的域名 如果没有配置 还是使用的ip地址 这样就会造成一个现象 在开发工具上以及真机调试时 都能正常运行 但预览就不行 但只要在预览时 打开
  • c++如何使用yaml来进行配置

    c 如何使用yaml来进行配置 yaml的基本语法可以参考这个博客 https www cnblogs com sddai p 9626392 html yaml的使用也可以参考这个博客 https www it610 com articl
  • 基础算法题——迷宫(递推)

    迷宫 题目链接 解题思路 暴力法 利用 dfs 遍历每一条可能的路径 将遍历的权值和不断取余 不足 当 n m 取较大的情况下 所遍历的路径可能会暴增 出现超时的情况 递推法 从题目上我们可以发现 最终的权值和是要对 mod 取余的 利用这
  • 查询SQLSERVER执行过的SQL记录(历史查询记录)

    有的时候 需要知道近段时间SQLSERVER执行了什么语句 可以用下面的方法 SELECT TOP 1000 QS creation time SUBSTRING ST text QS statement start offset 2 1
  • Linux教程系列 pdf下载(鸟哥私房菜等)

    鸟哥的Linux私房菜 基础篇 第四版 pdf 下载 LINUX内核设计与实现 pdf 下载 Linux 操作系统 基础操作 教学 doc 下载 linux内核深入剖析基于0 11 pdf 下载 Linux系统命令及其使用详解 doc 下载
  • 静态变量与动态变量的区别

    目录 一 定义 1 变量与常量 2 局部变量 局部变量 定义在函数中的变量 3 全局变量 4 动态变量和静态变量 二 区别 1 局部变量与全局变量的对比 2 静态变量与动态变量 一 定义 1 变量与常量 变量 指的是在程序运行过程中 可以通
  • Linux 高级进程管理

    1 让出处理器 Linux提供一个系统调用运行进程主动让出执行权 sched yield 进程运行的好好的 为什么需要这个函数呢 有一种情况是用户空间线程的锁定 如果一个线程试图取得另一个线程所持有的锁 则新的线程应该让出处理器知道该锁变为