Linux线程调度实验

简介: Linux线程调度实验

Linux线程调度实验

1.获取线程属性

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#define _GNU_SOURCE
#define handle_error_en(en, msg) \
               do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
static void display_pthread_attr(pthread_attr_t *attr, char *prefix){
    int s, i;
    size_t v;
    void *stkaddr;
    struct  sched_param sp;
    s = pthread_attr_getdetachstate(attr, &i);
    if (s != 0) 
        handle_error_en(s, "pthread_attr_getdetachstate");
    printf("%sDetach state        = %s\n", prefix,
            (i == PTHREAD_CREATE_DETACHED) ? "PTHREAD_CREATE_DETACHED" :
            (i == PTHREAD_CREATE_JOINABLE) ? "PTHREAD_CREATE_JOINABLE" :
            "???");
    s = pthread_attr_getscope(attr, &i);
    if (s != 0)
        handle_error_en(s, "pthread_attr_getscope");
    printf("%sScope               = %s\n", prefix,
            (i == PTHREAD_SCOPE_SYSTEM)  ? "PTHREAD_SCOPE_SYSTEM" :
            (i == PTHREAD_SCOPE_PROCESS) ? "PTHREAD_SCOPE_PROCESS" :
            "???");
    s = pthread_attr_getinheritsched(attr, &i);
    if (s != 0)
        handle_error_en(s, "pthread_attr_getinheritsched");
    printf("%sInherit scheduler   = %s\n", prefix,
            (i == PTHREAD_INHERIT_SCHED)  ? "PTHREAD_INHERIT_SCHED" :
            (i == PTHREAD_EXPLICIT_SCHED) ? "PTHREAD_EXPLICIT_SCHED" :
            "???");
    s = pthread_attr_getschedpolicy(attr, &i);  
    if (s != 0)  
        handle_error_en(s, "pthread_attr_getschedpolicy");  
    printf("%sScheduling policy   = %s\n", prefix,  
        (i == SCHED_OTHER) ? "SCHED_OTHER" :  
        (i == SCHED_FIFO)  ? "SCHED_FIFO" :  
        (i == SCHED_RR)    ? "SCHED_RR" :  
        "???");  
    s = pthread_attr_getschedparam(attr, &sp);  
    if (s != 0)  
        handle_error_en(s, "pthread_attr_getschedparam");  
    printf("%sScheduling priority = %d\n", prefix, sp.sched_priority);  
    s = pthread_attr_getguardsize(attr, &v);  
    if (s != 0)  
        handle_error_en(s, "pthread_attr_getguardsize");  
    printf("%sGuard size          = %zu bytes\n", prefix, v);  
    s = pthread_attr_getstack(attr, &stkaddr, &v);  
    if (s != 0)  
        handle_error_en(s, "pthread_attr_getstack");  
    printf("%sStack address       = %p\n", prefix, stkaddr);  
    printf("%sStack size          = 0x%zx bytes\n", prefix, v);  
}
void* computing(void* arg){
    int s;
    pthread_attr_t gattr;
    s = pthread_getattr_np(pthread_self(), &gattr);
    if (s != 0)
        handle_error_en(s, "pthread_getattr_np");
    printf("Thread attributes:\n");
    display_pthread_attr(&gattr, "\t");
    pause();
    pthread_exit(0);
}
int main(){
    pthread_t tid;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    // 线程创建函数
    pthread_create(&tid, &attr, computing, NULL);
    // 等待指定的线程结束
    pthread_join(tid,NULL);
    return 0;
}

这个库函数报错不用管

我们可以看到当前进程:

datach state:这个进程是一个joinable,也就是一个可进入等待状态的进程

scope:有两种状态

这两个的区别

一个是系统范围,一个是进程范围,如果我有多个线程,那么他们的竞争区间是在自己的进程内,还是整个系统的进程内

系统范围竞争

进程内竞争

我们linux系统的线程是系统范围竞争,我们前面学了用户模型和系统模型1对1模型,其实linux就是1

inherit schedule:调度器是谁

这里可以看出是继承调度,调度器的参数和属性会被这个进程所继承。

执行策略是:SCHED_OTHER

下面两个fifo和RR一个是先进先出,一个是时间片

Linux线程调度策略总共有两种:

  1. Normal Scheduling(正常调度):总共有三种,分别为SCHED_OTHER,SCHED_IDLE,SCHED_BATCH, 它的优先级数值priority_value需要设置成0,但这里并不一定意味着这个进程优先级很高,因为这个0是默认值。
  2. Real_time Schedulig(实时调度):总共有两种:一种是SCHED_FIFO(先来先服务),SCHED_RR(时间片轮转),实时调度的进程总是比正常调度的进程优先级要高,它的优先级数值priority_value∈[1,99],这里和前面我们学的系统优先级不同,1是低优先级,99是高优先级

实时调度需要延迟非常低才可以实现,所以现在用户模式的进程基本都是一般都是正常调度的。

这里SCHED_OTHER是RR,现在默认的状态是这个。

linux中优先级越低,进程或线程的优先级越高

PR值越高优先级越低

一般nice值默认为0

SCHED_IDLE:一般是周期性计划任务,清理磁盘等,优先级不是很高。

可以使用 ps -eLl来查看当前线程

LWP, light weight process 这里是4544和4545是用户模式产生的线程id

NLWP,Number of Light-Weight Processes

我们再用top看下

PR值为rt(实时进程)、负数(实时进程)、0(优先级极高),默认值20。

NI(nice)值:默认为0

top -p 4544

单看下当前进程的调度策略

看一个real time的进程

nice值仅在用户模式下有用

Real_time Scheduling【包含FIFO和RR】:

它的PR值计算公式为:PR = -1 - priority_value

所以PR∈[-100,-2]

可以看出左轴从-1开始都是rt的进程

所以我们可以通过PR值来判断一个进程/线程是Noraml Thread还是Real-time thread,是正数就

是Noraml Thread,是负数就是Real-time thread。

PR值=100

-r转化成RR策略的rt进程

-f转化成Fifo策略的rt进程

value 1~99 , 99代表优先级最高

我们把我们执行的这个进程转为fifo策略的real time 进程

sudo chrt -f -p 11 4544

-1-value

相关文章
|
8月前
|
存储 Linux API
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
在计算机系统的底层架构中,操作系统肩负着资源管理与任务调度的重任。当我们启动各类应用程序时,其背后复杂的运作机制便悄然展开。程序,作为静态的指令集合,如何在系统中实现动态执行?本文带你一探究竟!
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
|
6月前
|
并行计算 Linux
Linux内核中的线程和进程实现详解
了解进程和线程如何工作,可以帮助我们更好地编写程序,充分利用多核CPU,实现并行计算,提高系统的响应速度和计算效能。记住,适当平衡进程和线程的使用,既要拥有独立空间的'兄弟',也需要在'家庭'中分享和并行的成员。对于这个世界,现在,你应该有一个全新的认识。
267 67
|
4月前
|
存储 负载均衡 算法
Linux2.6内核进程调度队列
本篇文章是Linux进程系列中的最后一篇文章,本来是想放在上一篇文章的结尾的,但是想了想还是单独写一篇文章吧,虽然说这部分内容是比较难的,所有一般来说是简单的提及带过的,但是为了让大家对进程有更深的理解与认识,还是看了一些别人的文章,然后学习了学习,然后对此做了总结,尽可能详细的介绍明白。最后推荐一篇文章Linux的进程优先级 NI 和 PR - 简书。
136 0
|
8月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
141 26
|
8月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
148 17
|
9月前
|
算法 安全 Java
Java线程调度揭秘:从算法到策略,让你面试稳赢!
在社招面试中,关于线程调度和同步的相关问题常常让人感到棘手。今天,我们将深入解析Java中的线程调度算法、调度策略,探讨线程调度器、时间分片的工作原理,并带你了解常见的线程同步方法。让我们一起破解这些面试难题,提升你的Java并发编程技能!
301 16
|
10月前
|
Linux Shell 网络安全
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
本指南介绍如何利用 HTA 文件和 Metasploit 框架进行渗透测试。通过创建反向 shell、生成 HTA 文件、设置 HTTP 服务器和发送文件,最终实现对目标系统的控制。适用于教育目的,需合法授权。
283 9
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
|
11月前
|
开发框架 Java .NET
.net core 非阻塞的异步编程 及 线程调度过程
【11月更文挑战第12天】本文介绍了.NET Core中的非阻塞异步编程,包括其基本概念、实现方式及应用示例。通过`async`和`await`关键字,程序可在等待I/O操作时保持线程不被阻塞,提高性能。文章还详细说明了异步方法的基础示例、线程调度过程、延续任务机制、同步上下文的作用以及如何使用`Task.WhenAll`和`Task.WhenAny`处理多个异步任务的并发执行。
210 1
|
11月前
|
人工智能 算法 大数据
Linux内核中的调度算法演变:从O(1)到CFS的优化之旅###
本文深入探讨了Linux操作系统内核中进程调度算法的发展历程,聚焦于O(1)调度器向完全公平调度器(CFS)的转变。不同于传统摘要对研究背景、方法、结果和结论的概述,本文创新性地采用“技术演进时间线”的形式,简明扼要地勾勒出这一转变背后的关键技术里程碑,旨在为读者提供一个清晰的历史脉络,引领其深入了解Linux调度机制的革新之路。 ###
|
11月前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
211 4