Linux源码阅读笔记05-进程优先级与调度策略-实战分析

简介: Linux源码阅读笔记05-进程优先级与调度策略-实战分析

基础知识

  1. Linux 内核当中有 3 种调度策略:
  • SCHED_OTHER 分时调度策略;
  • SCHED_FIFO 实时调度策略,先到先服务;
  • SCHED_RR 实时调度策略,时间片轮转。

如果有相同优先级的实时进程(根据优先级计算的调度权值是一样的)已经准备好,FIFO 时必须等待该进程主动放弃之后才可以运行这个优先级相同的任务。而 RR 可以每个任务都执行一段时间。

  1. 获取线程设置的最高和最低优先级函数
  • int sched_get_priority_max(int policy)获取实时优先级的最大值;
  • int sched_get_priority_min(int policy)获取实时优先级的最小值;

SCHED_OTHER它 不 支 持 优 先 级 使 用 , 而SCHED_RR/SCHED_FIFO 支持优先级使用,它们分别为 1-99,数值越大优先级越高。

实时调度策略(SCHED_FIFO/SCHED_RR)优先级最大值为99;普通调度策略

(SCHED_NORMAL/SCHED_BATCH/SCHED_IDLE),始终返回0,即普通任务调度的函数。

  1. 设置和获取优先级的2个主要核心参数
  • int pthread_attr_setschedparam(pthread_attr_t* attr, const struct sched_param* param);设置线程优先级;
  • int pthread_attr_getschedparam(pthread_attr_t* attr, const struct sched_param* param);获取线程优先级;
struct sched_param {
    int __sched_priority; // 所有设定的线程优先级
}
param.sched_priority = 11; // 设置优先级
  1. 当操作系统创建线程时,默认线程是 SCHED_OTHER,我们也可以通过改变调度策略,使用如下函数:
  • int pthread_attr_setschedpolicy(pthread_attr_t* attr, int policy);设置线程调度策略;

基础案例分析

  1. 操作系统所支持优先级测试程序分析:
#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <assert.h>
static int GetThreadPolicyFunc(pthread_attr_t *pAttr)
{
    int iPlicy;
    int igp=pthread_attr_getschedpolicy(pAttr,&iPlicy);
    assert(igp==0);
    switch (iPlicy)
    {
    case SCHED_FIFO:
        printf("Policy is --> SCHED_FIFO.\n");
        break;
    case SCHED_RR:
        printf("Policy is --> SCHED_RR.\n");
        break;
    case SCHED_OTHER:
        printf("Policy is --> SCHED_OTHER.\n");
        break;
    
    default:
    printf("Policy is --> Unknown.\n");
        break;
    }
    return iPlicy;
}
static void PrintThreadPriorityFunc(pthread_attr_t *pAttr,int iPolicy)
{
    int iPriority=sched_get_priority_max(iPolicy); 
    assert(iPriority!=-1);
    printf("Max_priority is : %d\n",iPriority);
    iPriority=sched_get_priority_min(iPolicy); 
    assert(iPriority!=-1);
    printf("Min_priority is : %d\n",iPriority);
}
static int GetThreadPriorityFunc(pthread_attr_t *pAttr)
{
    struct sched_param sParam;
    int irs=pthread_attr_getschedparam(pAttr,&sParam);
    assert(irs==0);
    printf("Priority=%d\n",sParam.__sched_priority);
    return sParam.__sched_priority;
}
static void SetThreadPolicyFunc(pthread_attr_t *pAttr,int iPolicy)
{
    int irs=pthread_attr_setschedpolicy(pAttr,iPolicy);
    assert(irs==0);
    GetThreadPolicyFunc(pAttr);
}
int main(int argc,char *argv[])
{
    pthread_attr_t pAttr;
    struct sched_param sched;
    int irs=pthread_attr_init(&pAttr);
    assert(irs==0);
    int iPlicy=GetThreadPolicyFunc(&pAttr);
    printf("\nExport current Configuration of priority.\n");
    PrintThreadPriorityFunc(&pAttr,iPlicy);
    printf("\nExport SCHED_FIFO of prioirty.\n");
    PrintThreadPriorityFunc(&pAttr,SCHED_FIFO);
    printf("\nExport SCHED_RR of prioirty.\n");
    PrintThreadPriorityFunc(&pAttr,SCHED_RR);
    printf("\nExport priority of current thread.\n");
    int iPriority=GetThreadPriorityFunc(&pAttr);
    printf("Set thread policy.\n");
    printf("\nSet SCHED_FIFO policy.\n");
    SetThreadPolicyFunc(&pAttr,SCHED_FIFO);
    printf("\nSet SCHED_RR policy.\n");
    SetThreadPolicyFunc(&pAttr,SCHED_RR);
    printf("\nRestore current policy.\n");
    SetThreadPolicyFunc(&pAttr,iPlicy);
    irs=pthread_attr_destroy(&pAttr);
    assert(irs==0);
    return 0;
}

  1. 简单线程调度策略,我们创建三个线程,默认创建的线程它的调度策略为SCHED_OTHER,另外两个线程调度策略为 SCHED_RR/FIFO:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
void ThreadFunc1() {
    sleep(1);
    int i, j;
    int policy;
    struct sched_param param;
    pthread_getschedparam(pthread_self(), &policy, &param);
    switch (policy) {
    case SCHED_OTHER:
        printf("SCHED_OTHER\n");
        break;
    case SCHED_FIFO:
        printf("SCHED_FIFO\n");
    case SCHED_RR:
        printf("SCHED_RR Thread1\n");
    default:
        break;
    }
    for(i = 1; i <= 5; i++){
        for(j = 1; j <= 5000000; j++){}
        printf("Execute thread function 1.\n");
    }
    printf("ThreadFunc1 Exit\n");
}
void ThreadFunc2() {
    sleep(2);
    int policy;
    struct sched_param param;
    pthread_getschedparam(pthread_self(), &policy, &param);
    switch(policy) {
    case SCHED_OTHER:
        printf("SCHED_OTHER\n");
        break;
    case SCHED_FIFO:
        printf("SCHED_FIFO\n");
        break;
    case SCHED_RR:
        printf("SCHED_RR Thread2");
        break;
    }
    for(int i = 1; i <= 6; i++){
        for(int j = 1; j <= 6000000; j++){}
        printf("Execute thread function 2.\n");
    }
    printf("ThreadFunc2 Exit\n");
}
void ThreadFunc3() {
    sleep(3);
    int policy;
    struct sched_param param;
    pthread_getschedparam(pthread_self(), &policy, &param);
    switch(policy) {
    case SCHED_OTHER:
        printf("SCHED_OTHER\n");
        break;
    case SCHED_FIFO:
        printf("SCHED_FIFO\n");
        break;
    case SCHED_RR:
        printf("SCHED_RR\n");
        break;
    }
    for(int i = 1; i <= 7; i++) {
        for(int j = 0; j <= 7000000; j++){}
        printf("Execute thread function 3.\n");
    }
    printf("ThreadFunc3 Exit\n");
}
int main(int argc, char* argv[]) {
    int i = 0;
    i = getuid();
    if(i == 0) {
        printf("The current user is root.\n\n");
    }
    else {
        printf("The current user is not root.\n\n");
    }
    pthread_t pid1, pid2, pid3;
    struct sched_param param;
    pthread_attr_t attr1, attr2, attr3;
    pthread_attr_init(&attr1);
    pthread_attr_init(&attr2);
    pthread_attr_init(&attr3);
    param.sched_priority = 31;
    pthread_attr_setschedpolicy(&attr2, SCHED_RR);
    pthread_attr_setschedparam(&attr2, &param);
    pthread_attr_setinheritsched(&attr2, PTHREAD_EXPLICIT_SCHED);
    param.sched_priority = 11;
    pthread_attr_setschedpolicy(&attr1, SCHED_FIFO);
    pthread_attr_setschedparam(&attr1, &param);
    pthread_attr_setinheritsched(&attr1, PTHREAD_EXPLICIT_SCHED);
    pthread_create(&pid3, &attr3, (void*)ThreadFunc3, NULL);
    pthread_create(&pid2, &attr2, (void*)ThreadFunc2, NULL);
    pthread_create(&pid1, &attr1, (void*)ThreadFunc1, NULL);
    pthread_join(pid3, NULL);
    pthread_join(pid2, NULL);
    pthread_join(pid1, NULL);
    pthread_attr_destroy(&attr3);
    pthread_attr_destroy(&attr2);
    pthread_attr_destroy(&attr1);
    return 0;
}
  • 超级用户运行

相关文章
|
1月前
|
算法 调度 UED
深入理解操作系统:进程调度与优先级队列
【10月更文挑战第31天】在计算机科学的广阔天地中,操作系统扮演着枢纽的角色,它不仅管理着硬件资源,还为应用程序提供了运行的环境。本文将深入浅出地探讨操作系统的核心概念之一——进程调度,以及如何通过优先级队列来优化资源分配。我们将从基础理论出发,逐步过渡到实际应用,最终以代码示例巩固知识点,旨在为读者揭开操作系统高效管理的神秘面纱。
|
20天前
|
调度 开发者
核心概念解析:进程与线程的对比分析
在操作系统和计算机编程领域,进程和线程是两个基本而核心的概念。它们是程序执行和资源管理的基础,但它们之间存在显著的差异。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
38 4
|
1月前
|
运维 JavaScript jenkins
鸿蒙5.0版开发:分析CppCrash(进程崩溃)
在HarmonyOS 5.0中,CppCrash指C/C++运行时崩溃,常见原因包括空指针、数组越界等。系统提供基于posix信号机制的异常检测能力,生成详细日志辅助定位。本文详解CppCrash分析方法,涵盖异常检测、问题定位思路及案例分析。
50 4
|
1月前
|
运维 监控 JavaScript
鸿蒙next版开发:分析JS Crash(进程崩溃)
在HarmonyOS 5.0中,JS Crash指未处理的JavaScript异常导致应用意外退出。本文详细介绍如何分析JS Crash,包括异常捕获、日志分析和典型案例,帮助开发者定位问题、修复错误,提升应用稳定性。通过DevEco Studio收集日志,结合HiChecker工具,有效解决JS Crash问题。
50 4
|
2月前
|
算法 调度
深入理解操作系统:进程调度与优先级反转问题
【9月更文挑战第36天】操作系统是计算机科学中的核心概念,它管理着计算机的硬件资源和软件进程。在多任务处理环境中,进程调度是保证系统高效运行的关键机制之一。本文将探讨进程调度的基本概念、调度算法以及它们如何影响系统性能。同时,我们还将讨论优先级反转问题,这是一个在实时系统中常见的问题,它可能导致系统响应时间不可预测。通过分析优先级反转的原因和解决方案,我们可以更好地理解操作系统的设计和优化策略。
|
2月前
|
数据挖掘 程序员 调度
探索Python的并发编程:线程与进程的实战应用
【10月更文挑战第4天】 本文深入探讨了Python中实现并发编程的两种主要方式——线程和进程,通过对比分析它们的特点、适用场景以及在实际编程中的应用,为读者提供清晰的指导。同时,文章还介绍了一些高级并发模型如协程,并给出了性能优化的建议。
37 3
|
3月前
|
存储 算法 前端开发
深入理解操作系统:进程调度与优先级队列算法
【9月更文挑战第25天】在操作系统的复杂世界中,进程调度是维持系统稳定运行的核心机制之一。本文将深入探讨进程调度的基本概念,分析不同的进程调度算法,并着重介绍优先级队列算法的原理和实现。通过简洁明了的语言,我们将一起探索如何优化进程调度,提高操作系统的效率和响应速度。无论你是计算机科学的初学者还是希望深化理解的专业人士,这篇文章都将为你提供有价值的见解。
|
3月前
|
算法 调度
深入理解操作系统:进程调度与优先级反转
【9月更文挑战第21天】在操作系统的心脏跳动着的,是进程调度器。它决定了哪个进程运行,何时运行,以及如何优雅地共享CPU资源。本文将通过浅显易懂的语言和直观的代码示例,探索进程调度的奥秘,揭示优先级反转问题及其解决方案,带领读者领略操作系统中这一精妙绝伦的设计。
|
3月前
|
算法 人机交互 调度
进程调度算法_轮转调度算法_优先级调度算法_多级反馈队列调度算法
轮转调度算法(RR)是一种常用且简单的调度方法,通过给每个进程分配一小段CPU运行时间来轮流执行。进程切换发生在当前进程完成或时间片用尽时。优先级调度算法则根据进程的紧迫性赋予不同优先级,高优先级进程优先执行,并分为抢占式和非抢占式。多队列调度算法通过设置多个具有不同优先级的就绪队列,采用多级反馈队列优先调度机制,以满足不同类型用户的需求,从而优化整体调度性能。
131 15
|
3月前
|
监控 Linux Shell
30 个实用的 Linux 命令贴与技巧,提升你的效率(附实战案例)
本文介绍了30个实用的Linux命令及其应用场景,帮助你提升命令行操作效率。涵盖返回目录、重新执行命令、查看磁盘使用情况、查找文件、进程管理、网络状态监控、定时任务设置等功能,适合各水平的Linux用户学习和参考。
下一篇
DataWorks