当前位置: 首页 > news >正文

16 - 初探Linux进程调度

---- 整理自狄泰软件唐佐林老师课程

查看所有文章链接:(更新中)Linux系统编程训练营 - 目录

文章目录

  • 1. 初探Linux进程调度
    • 1.1 Linux系统调度
    • 1.2 进程调度原理
    • 1.3 Linux系统调度策略
    • 1.4 进程调度实验设计
      • 1.4.1 实验目标
      • 1.4.2 实验设计
    • 1.5 实验需解决的问题
      • 1.5.1 “固定”时间工作量估算
      • 1.5.2 获取/改变进程调度策略
      • 1.5.3 记录进程运行后产生数据
      • 1.5.4 图形化数据显示与分析
    • 1.6 编程实验:进程调度实验
      • 1.6.1 SCHED_OTHER
      • 1.6.2 SCHED_RR
      • 1.6.3 SCHED_FIFO

1. 初探Linux进程调度

已知:父进程创建子进程后,父子进程同时运行

  • 问题:如果计算机只有一个处理器,父子进程以什么方式同时执行?

1.1 Linux系统调度

  • 内核具有进程调度的能力,多个进程可同时运行
  • 微观上,处理器同一时间只能执行一个进程
  • 同时运行多个进程时,每个进程都会获得适当的执行时间片
  • 当执行时间片用完时,内核调度下一个进程执行

1.2 进程调度原理

  • n个进程(n >= 2)同时位于内存中
  • 处理器执行完每个进程,每个进程拥有一个时间片
  • 时间片用完,通过时钟中断完成进程切换(调度)
    在这里插入图片描述

1.3 Linux系统调度策略

  • 普通调度策略
    • SCHED_OTHER:Linux默认的调度策略,也被称为CFS(Completely Fair Scheduler),给每个进程动态计算优先级,根据优先级和进程执行的历史记录来确定下一个执行的进程。
  • 实时调度策略
    • SCHED_FIFO:基于优先级顺序调度进程,并在一个进程获得CPU时一直执行,直到进程主动释放。
    • SCHED_RR:基于“时间片轮转”的调度策略,给每个进程设置一个固定的时间片,并按照优先级顺序对进程进行轮流调度。

1.4 进程调度实验设计

1.4.1 实验目标

  1. 验证 同一时刻只有一个进程在执行
  2. 验证 不同调度策略,进程执行的连续性不同

1.4.2 实验设计

  1. n个进程同时运行,统计各个进程的执行时刻
  2. 进程运行方式:
    • 每个slice时间记录如下值:进程编号,当前时间值,完成度
    • 在total时间后结束运行,并输出记录的数据
    • 通过记录的数据分析进程调度策略

1.5 实验需解决的问题

  • 如何让进程每次“固定”工作slice时间(单位毫秒)?
  • 如何获取和改变进程的调度策略?
  • 如何记录数据并输出数据(需要保存数据)?
  • 如何图形化显示数据?

1.5.1 “固定”时间工作量估算

  • Linux中的时间获取

在这里插入图片描述
在这里插入图片描述

1.5.2 获取/改变进程调度策略

在这里插入图片描述

  • chrt命令简介
    Linux系统中可以使用chrt命令来查看、设置一个进程的优先级和调度策略
  • 命令用法

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

1.5.3 记录进程运行后产生数据

在这里插入图片描述

1.5.4 图形化数据显示与分析

在这里插入图片描述

1.6 编程实验:进程调度实验

【参看链接】:16 - 初探Linux进程调度

  • taskset实验

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 进程调度实验
#include <sys/wait.h>
#include <sys/resource.h>
#include <time.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sched.h>
#include <fcntl.h>#define NLOOP_FOR_ESTIMATION 1000000000UL
#define NSECS_PER_MSEC 1000000UL
#define NSECS_PER_SEC 1000000000UL#define DiffNS(begin, end) ((end.tv_sec - begin.tv_sec) * NSECS_PER_SEC \+ (end.tv_nsec - begin.tv_nsec))static unsigned long g_load_per_slice;
static struct timespec g_time_begin;static unsigned long estimate_loops_per_msec() // 1ms有多少次循环
{struct timespec begin = {0};struct timespec end   = {0};unsigned long i = 0;clock_gettime(CLOCK_MONOTONIC, &begin);while (i < NLOOP_FOR_ESTIMATION) i++;clock_gettime(CLOCK_MONOTONIC, &end);return NLOOP_FOR_ESTIMATION / (DiffNS(begin, end) / NSECS_PER_MSEC);
}static inline void work()
{unsigned int i = 0;// g_load_per_slice 每个时间片的循环次数// 经过 1 个时间片的循环次数后返回,模拟工作 1 个时间片while (i < g_load_per_slice) i++;
}static void test(int id, struct timespec* tss, int nrecord)
{struct timespec ts = {0};char buf[128] = {0};int fd = -1;int i = 0;// nrecord 记录的时间片数,也就是进程要执行的总时间for (i = 0; i < nrecord; i++) {work();clock_gettime(CLOCK_MONOTONIC, tss + i);}sprintf(buf, "./%d-proc.log", id);printf("%s\n", buf);fd = open(buf, O_WRONLY | O_CREAT | O_TRUNC);if (fd != -1) {for (i = 0; i < nrecord; i++) {sprintf(buf, "%d\t%ld\t%d\n",id,DiffNS(g_time_begin, tss[i]) / NSECS_PER_MSEC,(i + 1) * 100 / nrecord);write(fd, buf, strlen(buf));}}close(fd);
}int main(int argc, char* argv[])
{int nproc = atoi(argv[1]); // 创建多少个进程int total = atoi(argv[2]); // 每个进程需要执行的时间int slice = atoi(argv[3]); // 时间片int nrecord = total / slice;// 申请记录 nrecord 条记录的 logbufstruct timespec* logbuf = malloc(nrecord * sizeof(*logbuf));pid_t* pids = malloc(nproc * sizeof(*pids));total = total / slice * slice;if (logbuf && pids) {int i = 0;int n = 0;printf("nproc = %d\n", nproc);printf("total = %d\n", total);printf("slice = %d\n", slice);printf("SCHED_OTHER = %d\n", SCHED_OTHER);printf("SCHED_FIFO  = %d\n", SCHED_FIFO);printf("SCHED_RR    = %d\n", SCHED_RR);printf("Begin estimate work load per slice...\n");g_load_per_slice = estimate_loops_per_msec() * slice; // 每个时间片的循环次数printf("End ==> g_load_per_slice = %ld\n", g_load_per_slice);clock_gettime(CLOCK_MONOTONIC, &g_time_begin); // 统计的起始时间for (i = 0; i < nproc; i++) {pids[i] = fork();if (pids[i] < 0) {int j = 0;while (j < n) {kill(pids[j++], SIGKILL); // 杀死创建成功的子进程}printf("Process create error...\n");break;} else if (pids[i] == 0) {int sched = sched_getscheduler(0);int pri = getpriority(PRIO_PROCESS, 0);printf("task %d ==> schedule policy: %d\n", i, sched);printf("task %d ==> schedule priority: %d\n", i, pri);test(i, logbuf, nrecord);exit(0);} else {n++;}}}free(logbuf);free(pids);return 0;
}
import sys
import numpy as np
import matplotlib.pyplot as pltflag = sys.argv[1]
nproc = int(sys.argv[2])data = []
colors = []for fid in range(0, nproc):fname = str(fid) + '-proc.log'fd = open(fname, 'r')lines = fd.readlines()for s in lines:s = s.strip().split('\t')data.append( [int(s[0]), int(s[1]), int(s[2])] )fd.close()color = '#'for c in np.random.randint(0, 255, 3):color += format(c, '02X')colors.append(color)x_value = []
y_value = []
c_value = []if flag == 'id-time':for d in data:y_value.append(d[0])x_value.append(d[1])c_value.append(colors[d[0]])plt.scatter(x_value, y_value, c=c_value)plt.title('Data Analysis')plt.ylabel('Process No.')plt.xlabel('TIme(ms)')plt.show()if flag == 'work-time':for d in data:y_value.append(d[2])x_value.append(d[1])c_value.append(colors[d[0]])plt.scatter(x_value, y_value, c=c_value)plt.title('Data Analysis')plt.ylabel('Work Load')plt.xlabel('TIme(ms)')plt.show()

1.6.1 SCHED_OTHER

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.6.2 SCHED_RR

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.6.3 SCHED_FIFO

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

相关文章:

16 - 初探Linux进程调度

---- 整理自狄泰软件唐佐林老师课程 查看所有文章链接&#xff1a;&#xff08;更新中&#xff09;Linux系统编程训练营 - 目录 文章目录 1. 初探Linux进程调度1.1 Linux系统调度1.2 进程调度原理1.3 Linux系统调度策略1.4 进程调度实验设计1.4.1 实验目标1.4.2 实验设计 1.5 实…...

Huggingface使用

文章目录 前置安装Huggingface介绍NLP模块分类transformer流程模块使用详细讲解tokennizermodeldatasetsTrainer Huggingface使用网页直接体验API调用本地调用(pipline)本地调用&#xff08;非pipline&#xff09; 前置安装 anaconda安装 使用conda创建一个新环境并安装pytorc…...

Android 刷新与显示

目录 屏幕显示原理&#xff1a; 显示刷新的过程 VSYNC机制具体实现 小结&#xff1a; 屏幕显示原理&#xff1a; 过程描述&#xff1a; 应用向系统服务申请buffer 系统服务返回一个buffer给应用 应用开始绘制&#xff0c;绘制完成就提交buffer&#xff0c;系统服务把buffer数据…...

三行命令在CentOS 8上安装FFmpeg

添加RPMfusion仓库 yum install https://download1.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpm 安装SDL yum install http://rpmfind.net/linux/epel/7/x86_64/Packages/s/SDL2-2.0.14-2.el7.x86_64.rpm 安装FFmpeg yum install ffmpeg 执行命令测试 [rootVM…...

【前端】html

HTML标签&#xff08;上&#xff09; 目标&#xff1a; -能够说出标签的书写注意规范 -能够写出HTML骨架标签 -能够写出超链接标签 -能够写出图片标签并说出alt和title的区别 -能够说出相对路径的三种形式 目录&#xff1a; HTML语法规范HTML基本结构标签开发工具HTML常用标…...

【RealTek sdk-3.4.14b】Realtek WiFi开发调试指令总结

格式说明 RTL8192cd 驱动程序提供 MIB 接口&#xff0c;可通过“iwpriv”命令获取/设置参数。 set_mib iwpriv set_mib namevalue1[,value2,value3…]” Iface: “wlan0” value: 1.值可以是单个字段&#xff0c;也可以是用“&#xff0c;”分隔的多个字段&#xff0c;字…...

基于Vue 的文本类弹框代码Demo

<template><div class"text-popup" v-if"showPopup"><h2>{{ title }}</h2><p>{{ content }}</p><button click"closePopup">关闭</button></div><div class"main-content"&…...

2023.08.01 驱动开发day8

驱动层 #include <linux/init.h> #include <linux/module.h> #include <linux/of.h> #include <linux/of_irq.h> #include <linux/interrupt.h> #include <linux/fs.h> #include <linux/gpio.h> #include <linux/of_gpio.h>#…...

计算机视觉--距离变换算法的实战应用

前言&#xff1a; Hello大家好&#xff0c;我是Dream。 计算机视觉CV是人工智能一个非常重要的领域。 在本次的距离变换任务中&#xff0c;我们将使用D4距离度量方法来对图像进行处理。通过这次实验&#xff0c;我们可以更好地理解距离度量在计算机视觉中的应用。希望大家对计算…...

MIT 6.824 -- MapReduce -- 01

MIT 6.824 -- MapReduce -- 01 引言抽象和实现可扩展性可用性(容错性)一致性MapReduceMap函数和Reduce函数疑问 课程b站视频地址: MIT 6.824 Distributed Systems Spring 2020 分布式系统 推荐伴读读物: 极客时间 – 大数据经典论文解读DDIA – 数据密集型应用大数据相关论文…...

概念解析 | 利用IAA迭代自适应方法实现高精度角度估计

利用IAA迭代自适应方法实现高精度角度估计 注1:本文系“概念辨析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:IAA迭代自适应方法在雷达角度估计中的应用。 背景介绍 在雷达目标检测与定位中,准确估计目标角度是实现高精度定位的关键。传统的基于…...

正则表达式必知必会

文章目录 前言匹配单个字符匹配任意字符匹配一组字符取非匹配元字符匹配数字匹配所有字母和数字匹配空白字符重复匹配避免过度匹配边界匹配字符串边界子表达式回溯引用回溯引用中的替换操作向前查找向后查找 前言 在工作中使用正则表达式可以提高我们的效率&#xff0c;这篇博…...

[SQL系列] 从头开始学PostgreSQL 分库分表

什么是分库分表 分库分表是一种数据库架构设计的方法&#xff0c;用于应对大规模数据的存储和查询。当单个数据库的存储容量或查询性能无法满足需求时&#xff0c;可以通过将数据分散存储在多个数据库服务器上&#xff0c;以提高系统的可扩展性和性能。 分库分表通常包…...

【VScode】Remote-SSH XHR failed无法访问远程服务器

问题概述 当使用VScode连接远程服务器时&#xff0c;往往需要使用Remote-SSH这个插件。而该插件有一个小bug&#xff0c;当远程服务器网络不佳时容易出现。 在控制台会出现下述语句&#xff1a; Resolver error: Error: XHR failed at y.onerror (vscode-file://vscode-app/…...

pycharm打开terminal报错

Pycharm打开终端报错如何解决&#xff1f;估计是终端启动conda不顺利&#xff0c;需要重新设置路径。参考以下文章的做法即可。 Windows下Pycharm中Terminal无法进入conda环境和Python Console 不能使用 给pycharm中Terminal 添加新的shell&#xff0c;才可以使用conda环境 W…...

C#与C/C++交互(1)——需要了解的基础知识

【前言】 C#中用于实现调用C/C的方案是P/Invoke&#xff08;Platform Invoke&#xff09;&#xff0c;让托管代码可以调用库中的函数。类似的功能&#xff0c;JAVA中叫JNI&#xff0c;Python中叫Ctypes。 常见的代码用法如下&#xff1a; [DllImport("Test.dll", E…...

LeetCode笔记:Weekly Contest 356

LeetCode笔记&#xff1a;Weekly Contest 356 1. 题目一 1. 解题思路2. 代码实现 2. 题目二 1. 解题思路2. 代码实现 3. 题目三 1. 解题思路2. 代码实现 4. 题目四 1. 解题思路2. 代码实现 比赛链接&#xff1a;https://leetcode.com/contest/weekly-contest-356/ 1. 题目一…...

2 Python的基础语法

概述 在上一节的内容中&#xff0c;我们介绍了Python的诞生、发展历程、特色、缺点和应用领域。从本节开始&#xff0c;我们将正式学习Python。Python是一门简洁和优雅的语言&#xff0c;有自己特殊的一些语法规则。因此&#xff0c;在介绍Python编程的有关知识之前&#xff0c…...

抖音seo矩阵系统源代码开发搭建技术分享

抖音SEO矩阵系统是一个较为复杂的系统&#xff0c;其开发和搭建需要掌握一定的技术。以下是一些技术分享&#xff1a; 技术分享 抖音SEO矩阵系统的源代码可以使用JAVA、Python、PHP等多种语言进行开发。其中&#xff0c;JAVA语言的应用较为广泛&#xff0c;因为JAVA语言有良好…...

python#django数据库一对一/一对多/多对多

一对一OneToOneField 用户和用户信息 搭建 # 一对一 class TestUser(models.Model): usernamemodels.CharField(max_length32) password models.CharField(max_length32) class TestInfo(models.Model): mick_namemodels.CharField(max_length32) usermode…...

避开这5个坑,你的癫痫脑电AI模型准确率能翻倍:从数据标注到特征工程实战

避开这5个坑&#xff0c;你的癫痫脑电AI模型准确率能翻倍&#xff1a;从数据标注到特征工程实战 在医疗AI领域&#xff0c;癫痫脑电信号分析一直是个充满挑战的课题。许多开发者满怀信心地构建模型&#xff0c;却在验证阶段遭遇性能瓶颈——准确率停滞不前&#xff0c;误报率居…...

保姆级教程:用CH34xSerCfg修改USB转串口芯片的VID/PID,解决驱动冲突和串口号固定问题

嵌入式开发实战&#xff1a;用CH34xSerCfg定制USB转串口设备标识与驱动管理 当你的工作台上同时连接着五个相同型号的USB转TTL模块&#xff0c;Windows设备管理器里COM端口像走马灯一样随机变换编号时&#xff1b;当团队协作开发中&#xff0c;每个成员需要固定识别自己的调试设…...

SOCD Cleaner终极指南:彻底解决游戏键盘方向冲突的免费开源神器

SOCD Cleaner终极指南&#xff1a;彻底解决游戏键盘方向冲突的免费开源神器 【免费下载链接】socd Key remapper for epic gamers 项目地址: https://gitcode.com/gh_mirrors/so/socd 还在为格斗游戏中同时按下W和S导致角色卡顿而烦恼吗&#xff1f;或者在射击游戏急停转…...

AI应用开发利器:ai-devkit工具包核心功能与工程实践指南

1. 项目概述与核心价值最近在折腾AI应用开发&#xff0c;发现一个挺有意思的项目&#xff0c;叫codeaholicguy/ai-devkit。乍一看名字&#xff0c;你可能会觉得这又是一个“AI开发工具包”&#xff0c;市面上类似的工具已经多如牛毛了。但深入用下来&#xff0c;我发现它不太一…...

荣品RV1126 SDK编译避坑指南:从环境配置到分区调整,手把手解决常见编译错误

RV1126 SDK编译实战&#xff1a;从环境搭建到分区优化的全流程解决方案 1. 开发环境配置与初始化 RV1126开发环境的搭建是整个开发流程的第一步&#xff0c;也是后续所有工作的基础。一个稳定、高效的开发环境能够显著提升开发效率&#xff0c;减少不必要的错误。 首先需要确保…...

开源自动驾驶系统终极指南:从入门到精通

开源自动驾驶系统终极指南&#xff1a;从入门到精通 【免费下载链接】openpilot openpilot is an operating system for robotics. Currently, it upgrades the driver assistance system on 300 supported cars. 项目地址: https://gitcode.com/GitHub_Trending/op/openpilo…...

NVIDIA Profile Inspector完整指南:200+隐藏设置解锁显卡极致性能

NVIDIA Profile Inspector完整指南&#xff1a;200隐藏设置解锁显卡极致性能 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 还在为游戏画面撕裂、输入延迟过高而烦恼吗&#xff1f;想要彻底掌控NVIDIA…...

Go语言实现跨平台系统更新检查器:自动化运维与安全监控实践

1. 项目概述&#xff1a;一个被低估的系统运维“哨兵”在服务器和桌面系统的日常运维中&#xff0c;有一个场景大家一定不陌生&#xff1a;某天&#xff0c;你管理的服务器突然因为一个已知漏洞被攻击&#xff0c;事后排查发现&#xff0c;相关的安全补丁其实在几周前就已经发布…...

轻量级工作流引擎pro-workflow:Go语言实现与实战解析

1. 项目概述&#xff1a;一个为专业开发者量身打造的工作流引擎如果你是一名开发者&#xff0c;尤其是经常需要处理复杂业务逻辑、数据流转或自动化任务的后端或全栈工程师&#xff0c;那么你一定对“工作流”这个概念不陌生。从简单的审批流到复杂的微服务编排&#xff0c;工作…...

基于RP2040与CircuitPython的键盘内嵌DOOM游戏启动器DIY指南

1. 项目概述与核心思路几年前&#xff0c;我还在用笨重的全尺寸键盘时&#xff0c;就总琢磨着怎么给这每天摸上八小时的家伙加点“私货”。直到后来玩起了RP2040和CircuitPython&#xff0c;一个念头就冒出来了&#xff1a;能不能把游戏直接“焊”进键盘里&#xff1f;不是那种…...