1. 程式人生 > >linux程序排程

linux程序排程

1. 程序排程類初始化

建立程序時,程序排程類的初始化在函式sched_fork()中進行

(kernel/sched/core.c)

int sched_fork(unsigned long clone_flags, struct task_struct *p)
{
    unsigned long flags;
    int cpu = get_cpu();

    __sched_fork(clone_flags, p);
    /*
     * We mark the process as running here. This guarantees that
     * nobody will actually run
it, and a signal or other external * event cannot wake it up and insert it on the runqueue either. */ p->state = TASK_RUNNING;---------------------------------------程序執行狀態設定 /* * Make sure we do not leak PI boosting priority to the child. */ p->prio = current->normal_prio;--------------------------------程序初始優先順序
/* * Revert to default priority/policy on fork if requested. */ if (unlikely(p->sched_reset_on_fork)) { if (task_has_dl_policy(p) || task_has_rt_policy(p)) { p->policy = SCHED_NORMAL; p->static_prio = NICE_TO_PRIO(0); p->rt_priority = 0
; } else if (PRIO_TO_NICE(p->static_prio) < 0) p->static_prio = NICE_TO_PRIO(0);---------------------靜態優先順序 p->prio = p->normal_prio = __normal_prio(p); set_load_weight(p); /* * We don't need the reset flag anymore after the fork. It has * fulfilled its duty: */ p->sched_reset_on_fork = 0; } if (dl_prio(p->prio)) { put_cpu(); return -EAGAIN; } else if (rt_prio(p->prio)) { p->sched_class = &rt_sched_class;--------------------\ } else { \ p->sched_class = &fair_sched_class;---------------------排程類設定 } if (p->sched_class->task_fork) p->sched_class->task_fork(p); /* * The child is not yet in the pid-hash so no cgroup attach races, * and the cgroup is pinned to this child due to cgroup_fork() * is ran before sched_fork(). * * Silence PROVE_RCU. */ raw_spin_lock_irqsave(&p->pi_lock, flags); set_task_cpu(p, cpu);-------------------------------------設定程序到某CPU raw_spin_unlock_irqrestore(&p->pi_lock, flags); #ifdef CONFIG_SCHED_INFO if (likely(sched_info_on())) memset(&p->sched_info, 0, sizeof(p->sched_info)); #endif #if defined(CONFIG_SMP) p->on_cpu = 0; #endif init_task_preempt_count(p); #ifdef CONFIG_SMP plist_node_init(&p->pushable_tasks, MAX_PRIO); RB_CLEAR_NODE(&p->pushable_dl_tasks); #endif put_cpu(); return 0; }

2. 執行佇列

系統的所有就緒佇列都在runqueues陣列中,陣列元素個數與cpu個數相關

DECLARE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);

核心中與佇列相關的一些巨集定義如下:

#define cpu_rq(cpu)     (&per_cpu(runqueues, (cpu)))
#define this_rq()       this_cpu_ptr(&runqueues)
#define task_rq(p)      cpu_rq(task_cpu(p))
#define cpu_curr(cpu)       (cpu_rq(cpu)->curr)
#define raw_rq()        raw_cpu_ptr(&runqueues)

執行佇列結構體如下:

struct rq {
    /* runqueue lock: */
    raw_spinlock_t lock;

    /*
     * nr_running and cpu_load should be in the same cacheline because
     * remote CPUs use both these fields when doing load calculation.
     */
    unsigned int nr_running;
#ifdef CONFIG_NUMA_BALANCING
    unsigned int nr_numa_running;
    unsigned int nr_preferred_running;
#endif
    #define CPU_LOAD_IDX_MAX 5
    unsigned long cpu_load[CPU_LOAD_IDX_MAX];
    unsigned long last_load_update_tick;
#ifdef CONFIG_NO_HZ_COMMON
    u64 nohz_stamp;
    unsigned long nohz_flags;
#endif
#ifdef CONFIG_NO_HZ_FULL
    unsigned long last_sched_tick;
#endif
    /* capture load from *all* tasks on this cpu: */
    struct load_weight load;
    unsigned long nr_load_updates;
    u64 nr_switches;

    struct cfs_rq cfs;
    struct rt_rq rt;
    struct dl_rq dl;

#ifdef CONFIG_FAIR_GROUP_SCHED
    /* list of leaf cfs_rq on this cpu: */
    struct list_head leaf_cfs_rq_list;
#endif /* CONFIG_FAIR_GROUP_SCHED */

    /*
     * This is part of a global counter where only the total sum
     * over all CPUs matters. A task can increase this counter on
     * one CPU and if it got migrated afterwards it may decrease
     * it on another CPU. Always updated under the runqueue lock:
     */
    unsigned long nr_uninterruptible;

    struct task_struct *curr, *idle, *stop;
    unsigned long next_balance;
    struct mm_struct *prev_mm;

    unsigned int clock_skip_update;
    u64 clock;
    u64 clock_task;

    atomic_t nr_iowait;

#ifdef CONFIG_SMP
    struct root_domain *rd;
    struct sched_domain *sd;

    unsigned long cpu_capacity;
    unsigned long cpu_capacity_orig;

    struct callback_head *balance_callback;

    unsigned char idle_balance;
    /* For active balancing */
    int active_balance;
    int push_cpu;
    struct cpu_stop_work active_balance_work;
    /* cpu of this runqueue: */
    int cpu;
    int online;

    struct list_head cfs_tasks;

    u64 rt_avg;
    u64 age_stamp;
    u64 idle_stamp;
    u64 avg_idle;

    /* This is used to determine avg_idle's max value */
    u64 max_idle_balance_cost;
#endif

#ifdef CONFIG_IRQ_TIME_ACCOUNTING
    u64 prev_irq_time;
#endif
#ifdef CONFIG_PARAVIRT
    u64 prev_steal_time;
#endif
#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
    u64 prev_steal_time_rq;
#endif

    /* calc_load related fields */
    unsigned long calc_load_update;
    long calc_load_active;

#ifdef CONFIG_SCHED_HRTICK
#ifdef CONFIG_SMP
    int hrtick_csd_pending;
    struct call_single_data hrtick_csd;
#endif
    struct hrtimer hrtick_timer;
#endif

#ifdef CONFIG_SCHEDSTATS
    /* latency stats */
    struct sched_info rq_sched_info;
    unsigned long long rq_cpu_time;
    /* could above be rq->cfs_rq.exec_clock + rq->rt_rq.rt_runtime ? */

    /* sys_sched_yield() stats */
    unsigned int yld_count;

    /* schedule() stats */
    unsigned int sched_count;
    unsigned int sched_goidle;

    /* try_to_wake_up() stats */
    unsigned int ttwu_count;
    unsigned int ttwu_local;
#endif

#ifdef CONFIG_SMP
    struct llist_head wake_list;
#endif

#ifdef CONFIG_CPU_IDLE
    /* Must be inspected within a rcu lock section */
    struct cpuidle_state *idle_state;
#endif
};

3. 排程類

核心中的排程類有下面幾項:

  • 空閒排程類:kernel/sehed/idle.c
  • 公平排程類:kernel/sehed/fair.c
  • 實時排程類:kernel/sehed/rt.c
  • 最後期限排程類:kernel/sehed/deadline.c

change log

date content linux
2016.12.4 初稿 linux4.6.3

相關推薦

linux 程序排程 pick_next_task()函式

pick_next_task是程序排程的關鍵步驟,主要功能是從發生排程的CPU的執行佇列中選擇一個程序執行。本文主要介紹該函式的實現過程。系統中的排程順序是:實時程序------->普通程序------>空閒程序。分別從屬於三個排程類:rt_sched_class

linux程序排程機制

版本宣告:轉載請註明出處,未經允許,禁止商業用途。 linux是以執行緒為單位進行CPU排程的。所以下面的描述中所說的執行緒和程序從CPU排程角度來說是等效。 Linux程序優先順序: Priority。程序的優先順序是作業系統自己給定並且動態調整的。使用者可以通過nice值來調整實際優先順序。 C

linux程序排程演算法

一:什麼是程序排程   都知道linux是一種多使用者多工的作業系統,而當多個程序同時執行去,搶佔有限資源的時候,這時作業系統就會按照一定的原則將資源合理分配給請求資源的程序,這就是程序排程。 二:在linux作業系統中都有哪些程序排程演算法   1. 先進先出演算法(

Linux 程序排程淺析

作業系統要實現多程序,程序排程必不可少。程序排程是對TASK_RUNNING狀態的程序進行排程(參見《linux程序狀態淺析》)。如果程序不可執行(正在睡眠或其他),那麼它跟程序排程沒多大關係。 所以,如果你的系統負載非常低,盼星星盼月亮才出現一個可執行狀態的程序。那麼程序排程也就不會太重要。哪個程序可執行

linux程序排程方法(SCHED_OTHER,SCHED_FIFO,SCHED_RR)

linux核心的三種排程方法: 1,SCHED_OTHER   分時排程策略, 2,SCHED_FIFO        實時排程策略,先到先服務 3,SCHED_RR          實時排程策略,時間片輪轉  分時程序則通過nice和counter值決定權值,nice

Linux程序排程器的設計--Linux程序的管理與排程(十七)

1 前景回顧 1.1 程序排程 記憶體中儲存了對每個程序的唯一描述, 並通過若干結構與其他程序連線起來. 排程器面對的情形就是這樣, 其任務是在程式之間共享CPU時間, 創造並行執行的錯覺, 該任務分為兩個不同的部分, 其中一個

Linux程序排程分析

原文:http://www.2cto.com/os/201112/113229.html 操作系統要實現多程序,程序排程必不可少。 有人說,程序排程是作業系統中最為重要的一個部分。我覺得這種說法說得太絕對了一點,就像很多人動輒就說"某某函式比某某函式效率高XX倍"一樣

Linux程序排程程序與執行緒的本質區別?

簡而言之,執行緒是程序的一部分,程序是程式的一部分。 異同: 1、程序是資源分配的基本單位,而執行緒是排程的基本單位; 2、程序與程序之間是獨立的,一個程序的異常終止不會影響其它程序,而執行緒與執行

linux程序排程

1. 程序排程類初始化 建立程序時,程序排程類的初始化在函式sched_fork()中進行 (kernel/sched/core.c) int sched_fork(unsigned long clone_flags, struct task_stru

Linux 程序排程小結

概述 這個問題又是面試常問問題,當時聽到感覺太寬泛了,有點大,心裡知道但是說不全,這裡做一下總結 【1】程序排程的作用 【2】排程德策略 1、 程序排程的作用 ,程序排程就是對程序進行排程,即負責選擇下一個要執行的程序.通過合理的排程,系統資源才能最大限度地發揮作用,多程

Linux程序排程CFS演算法實現分析

網上講CFS的文章很多,可能版本不一,理解不盡相同。我以問題追溯方式,跟蹤原始碼寫下我對CFS的理解,有的問題我也還沒理解透,歡迎對核心有興趣的朋友一起交流學習,原始碼版本是與LKD3配套的Linux2.6.34 背景知識: (1) Linux的排程器類主

linux程序排程演算法:分時排程策略、FIFO排程策略、RR排程策略

linux核心的三種排程方法: SCHED_OTHER 分時排程策略, SCHED_FIFO實時排程策略,先到先服務 SCHED_RR實時排程策略,時間片輪轉 注意: 實時程序將得到優先呼叫,實時程序根據實時優先順序決

程序排程演算法Linux程序排程演算法

這次介紹一下作業系統的程序排程演算法 作業系統的排程分為三種:1.遠端排程(建立新程序);2.中程排程(交換功能的一部分);3.短程排程(下次執行哪個程序) 這次講述的就是短程排程,可以簡單的看作咱們平

linux程序排程解析

1排程器的啟動通常有兩種方式:A. 主動式在核心應用中直接呼叫schedule()。這通常發生在因等待核心事件而需要將程序置於掛起(休眠)狀態的時候--這時應該主動請求排程以方便其他程序使用CPU。下面就是一個主動排程的例子:/* 節選自[drivers/input/mous

linux程序排程(2)

1.程序的排程 作為多程序的系統,Linux系統必須擔負起排程程序的責任,不斷地切換程序,以使CPU得到最大化的利用,提高系統的效率。 1.1 Linux程序排程的策略 程序排程的策略主要考慮以下幾個原則: (1) 高效 — 使處理器

Linux---程序排程相關命令解析

程序相關命令 1、ps  檢視系統中的程序 使用方式:ps [options] [--help] 說明:顯示瞬間程序 (process) 的動態 引數:ps的引數非常多, 在此僅列出幾個常用的引數並大略介紹含義 ps命令常用用法(方便檢視系統程序) 1)ps

Linux程序排程原理

本文系以下文章整理而來,並添加了自己的一些見解: (1)http://www.cnblogs.com/zhaoyl/archive/2012/09/04/2671156.html (2)http://os.51cto.com/art/201003/187407.htm (3

linux程序排程淺析

     作業系統要實現多程序,程序排程必不可少。      程序排程是對TASK_RUNNING狀態的程序進行排程(參見《linux程序狀態淺析》)。如果程序不可執行(正在睡眠或其他),那麼它跟程序排程沒多大關係。      所以,如果你的系統負載非常低,盼星星盼月亮才出現一個可執行狀態的程序。那麼程序

分析linux程序排程程序切換

慕課18原創作品轉載請註明出處 + 《Linux核心分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000 一、Linux程序排程時機主要有: (1)主動排程: 程序的執行狀態發生變化時,例如等待某些事件而

LINUX 程序排程演算法

程序排程:   無論是在批處理系統還是分時系統中,使用者程序數一般都多於處理機數、這將導致它們互相爭奪處理機。另外,系統程序也同樣需要使用處理機。 這就要求程序排程程式按一定的策略,動態地把處理機分配給處於就緒佇列中的某一個程序,以使之執行。 一、程序的基本狀態及狀