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

做网站赚钱吗 怎么赚深圳企业网站制作公司怎样

做网站赚钱吗 怎么赚,深圳企业网站制作公司怎样,完整网站源码下载,关键词免费下载进程调度1 策略I/O消耗型和处理器消耗型的进程进程优先级时间片进程抢占2 Linux调度算法可执行队列优先级数组重新计算时间片schedule()计算优先级和时间片睡眠和唤醒负载平衡程序3 抢占和上下文切换用户抢占内核抢占4 实时5 与调度相关的系统调用与调度策略和优先级相关的系统… 进程调度1 策略I/O消耗型和处理器消耗型的进程进程优先级时间片进程抢占2 Linux调度算法可执行队列优先级数组重新计算时间片schedule()计算优先级和时间片睡眠和唤醒负载平衡程序3 抢占和上下文切换用户抢占内核抢占4 实时5 与调度相关的系统调用与调度策略和优先级相关的系统调用与处理器绑定有关的系统调用放弃处理器时间6 调度程序小结调度程序是内核的组成部分它负责选择下一个要运行的进程。多任务操作系统就是能 同时并发地执行 多个进程的操作系统。多任务系统可以分为两类非抢占式多任务和抢占式多任务。 Linux提供抢占式的多任务模式。在此模式下由调度程序来决定什么时候 停止一个进程的运行以便其他进程能够得到执行。这个 强制停止动作叫做抢占注意这是强制停止不是进程自己停止。进程在被抢占之前能够运行的时间是预先设置好的而且有一个专门的名字叫进程的时间片。时间片实际上就是分配给每个 可运行进程的处理器时间段。在非抢占式多任务模式下除非进程自己主动停止运行否则它会一直运行。进程主动挂起自己的操作称为让步。Unix从一开始就是抢占式的多任务。1 策略 策略决定调度程序在何时让什么进程运行 I/O消耗型和处理器消耗型的进程 I/O消耗型进程大部分时间用来提交I/O请求或是等待I/O请求。因此这样的进程经常处于可运行状态但通常都是运行短短的一会儿因为I/O操作总会阻塞。 处理器消耗型把时间大多用在执行代码上。对于这类处理器消耗型的进程调度策略是尽量降低它们的运行频率对它们而言延迟其运行时间会更合适些。 I/O消耗型是尽量提高其运行频率降低运行时间处理器消耗型是降低其运行频率提高其运行时间。 Linux为了保证交互时应用对进程的响应做了优化缩短响应时间更倾向于优先调度I/O消耗型进程。 进程优先级 调度算法中最基本的一类就是基于优先级的调度。优先级高的进程先运行低的后运行相同优先级的进程按轮转方式进行调度一个接一个重复进行。在包括Linux在内的某些系统中优先级高的进程使用的时间片也较长。调度程序总是选择时间片未用尽而且优先级最高的进程运行。 Linux根据以上思想实现了一种基于动态优先级的调度方法。一开始该方法先设置基本的优先级然后允许调度程序根据需要来加减优先级。 Linux内核提供了两组独立的优先级范围。第一种是nice值范围是-20到19默认值是0。nice值越大优先级越低。另外nice值也用来决定分配给进程的时间片的长短nice值为-20的进程可能获得的时间片最长nice值为19的进程获得时间片可能最短。可能是因为时间片的长短还受其他因素影响。nice值是所有Unix系统都使用到的标准优先级范围。 第二个是实时优先级其值是可配置的默认情况下它的变化范围是从0到99任何实时进程的优先级都高于普通的进程。Linux提供了对POSIX实时优先级的支持。 时间片 时间片是一个数值它表明进程在被抢占前还能运行的时间。调度策略必须规定一个默认的时间片。 Linux调度程序提高交互式程序的优先级让它们运行更频繁。于是程序提供提供了较长默认时间片给交互程序。如下图 当一个进程的时间片耗尽时就认为进程到期了。没有时间片的进程不会再投入运行除非等他其他所有的进程都耗尽了它们的时间片系统会重算所有进程的时间片然后继续运行。 进程抢占 Linux系统是抢占式的。当一个进程进入TASK_RUNNING状态内核会检查它的优先级是否高于当前正在执行的进程。如果高于调度程序会被唤醒抢占当前正在运行的进程并运行高优先级的进程。此外当一个进程的时间片变为0调度程序被唤醒以选择一个新的进程。 2 Linux调度算法 Linux的调度程序定义于kernel/sched.c中。调度程序的算法和相关支持代码大部分都在2.5版内核的开发版中被重写了。因此现在的程序与以前版本内核的调度程序区别很大几乎是全新的。设计新的调度程序是为了实现以下目标 充分实现0(1)调度。不管有多少进程新调度程序采用的每个算法都能在恒定时间内完成。全面实现SMP的可拓展性。每个处理器都拥有自己的锁和自己的可执行队列强化SMP的可拓展性。尽量将相关的一组任务分配给一个CPU进行连续的执行。只有在需要平衡任务队列的大小时才在CPU之间移动进程加强交互性能。即使在系统处于相当负载的情况下也能保证系统的响应并立即调度交互式进程。保证公平。在合理设定的时间范围内没有进程会处于饥饿状态。 可执行队列 调度程序中最基本的数据结构是运行队列。可执行队列定义在kernel/sched.c中。由结构runqueue表示。可执行队列是给定处理器上的可执行进程的链表每个处理器一个。每个可投入运行的进程都唯一的归属于一个可执行队列。此外可执行队列中还包含每个处理器的调度信息。 /** This is the main, per-CPU runqueue data structure.** Locking rule: those places that want to lock multiple runqueues* (such as the load balancing or the thread migration code), lock* acquire operations must be ordered by ascending runqueue.*/ struct runqueue {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 long nr_running; /* 可运行任务的数目 */ #ifdef CONFIG_SMPunsigned long cpu_load; #endifunsigned long long nr_switches; /* 上下文切换数目 *//** 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; /* 处于不可中断睡眠状态的任务数目 */unsigned long expired_timestamp; /* 队列最后被换出时间 */unsigned long long timestamp_last_tick; /* 最后一个调度程序的节拍 */task_t *curr, *idle; /* 当前运行任务、该处理器的空任务 */struct mm_struct *prev_mm; /* 最后运行任务的mm_struct结构体 */prio_array_t *active, *expired, arrays[2];/* 活动优先级队列、超时优先级队列、实际优先级数组 */int best_expired_prio;atomic_t nr_iowait; /* 等待I/O操作的任务数目 */#ifdef CONFIG_SMPstruct sched_domain *sd;/* For active balancing */int active_balance;int push_cpu;task_t *migration_thread; /* 移出线程 */struct list_head migration_queue; /* 移出队列 */ #endif#ifdef CONFIG_SCHEDSTATS/* latency stats */struct sched_info rq_sched_info;/* sys_sched_yield() stats */unsigned long yld_exp_empty;unsigned long yld_act_empty;unsigned long yld_both_empty;unsigned long yld_cnt;/* schedule() stats */unsigned long sched_noswitch;unsigned long sched_switch;unsigned long sched_cnt;unsigned long sched_goidle;/* pull_task() stats */unsigned long pt_gained[MAX_IDLE_TYPES];unsigned long pt_lost[MAX_IDLE_TYPES];/* active_load_balance() stats */unsigned long alb_cnt;unsigned long alb_lost;unsigned long alb_gained;unsigned long alb_failed;/* try_to_wake_up() stats */unsigned long ttwu_cnt;unsigned long ttwu_attempts;unsigned long ttwu_moved;/* wake_up_new_task() stats */unsigned long wunt_cnt;unsigned long wunt_moved;/* sched_migrate_task() stats */unsigned long smt_cnt;/* sched_balance_exec() stats */unsigned long sbe_cnt; #endif };由于可执行队列是调度程序的核心数据结构体所以有一组宏定义用于获取与给定处理器或进程相关的可执行队列 cup_rq(process)用于返回给定处理器上的可执行队列的指针this_rq()返回当前处理器的可执行队列task_rq(task)返回给定进程所在的队列指针 在对可执行队列操作之前应该先锁住可执行队列用来防止队列被其他代码改动。此时需要用到task_rq_lock()和task_re_unlock()函数 struct runqueue *rq; unsigned long flags;rq task_rq_lock(task,flags); /* task是用到可执行队列的任务 */.../* 对任务的队列rq进行操作 */... task_rq_unlock(rq,flags);或者可以用this_rq_lock()来锁住当前的可执行队列用rq_unlock(struct runqueue *rq)释放给定队列上的锁。 为了避免死锁要锁住多个运行队列的代码必须按照同样的顺序获取这些锁可按照执行队列地址从低到高的顺序 /* 锁定 */ if (rq1 rq2)spin_lock(rq1-lock) else {if(re1 rq2){spin_lock(rq1-lock);spin_lock(rq2-lock);}else{spin_lock(rq2-lock);spin_lock(rq1-lock);} }/* 操作两个运行队列 *//* 释放锁 */ spin_unlock(rq1-lock); if(rq1 ! rq2)spin_unlock(rq2lock);这些步骤能通过double_rq_lock()和double_rq_unlock()自动完成。上面的步骤会被简化为 double_rq_lock(rq1,rq2);/* 操作两个运行队列 */double_rq_unlock(rq1,rq2);优先级数组 每个运行队列都有两个优先级数组一个活跃的和一个过期的。优先级数组在kernel/sched.c文件中被定义它是prio_array类型的结构体。 struct prio_array {unsigned int nr_active; /* 任务数目 */unsigned long bitmap[BITMAP_SIZE]; /* 优先级位图 */struct list_head queue[MAX_PRIO]; /* 优先级队列 */ };优先级数组是一种能够提供0(1)级算法复杂度的数据结构。优先级数组使可运行处理器的每一种优先级都包含一个相应的队列而这些队列包含对应优先级上的可执行进程链表。优先级还拥有一个优先机位图当需要查找当前系统内拥有最高优先级的可执行进程时它可以提高效率。 MAX_PRIO定义了系统拥有的优先级个数。默认是140BITMAP_SIZE是优先级位图数组的大小类型为unsigned long长整数型32位每一位代表一个优先级140个优先级需要5个长整型bitmap就正好含有五个数组项总共160位。一开始所有的位都被置为0当某个拥有一定优先级的进程开始执行时位图中相应的位就会被置为1.比如如果一个优先级为7的进程变为可执行状态第7位就被置为1。这样查找系统中最高的优先级就变成了查找位图中被设置的第一个位。Linux提供了sched_find_first_bit()函数来快速查找位图被设置的第一个位。 每个优先级还包含一个加做struct list_head的队列每个链表与一个给定的优先级相对应每个链表都包含该处理器队列上相应优先级的全部可运行进程。所以要找到下一个要运行的任务非常简单就像在链表中选择下一个元素一样对于给定的优先级按轮转方式调度任务。 nr_active是计数器表示该优先级数组内可执行进程的数目。 重新计算时间片 新的Linux为每个处理器维护两个优先级数组活动数组和过期数组。活动数组内的可执行队列上的进程都还有时间片剩余而过期数组内的可执行队列上的进程都用完了时间片。当一个进程的时间片用完时它会从活动数组移至到过期数组在移动前会重新计算时间片。 schedule() 选定下一个进程并让该进程执行是通过schedule()函数实现的。当内核代码想要休眠时会直接调用该函数另外如果有那个进程将被抢占那么该函数也会被唤起执行。 首先该函数在活动优先级数组中找到第一个被设置的位。该位对应着优先级最高的可执行进程。然后调度程序选择这个级别链表里的头一个进程。这就是系统中优先级最高的可执行程序也是马上会被调度执行的进程。 计算优先级和时间片 进程拥有一个初始的优先级叫做nice值。该数值变化范围是-20到19默认值是0。进程task_struct的static_prio变量存放着这个值。而调度程序要用到的动态优先级存放在prio变量里。动态优先级通过一个关于静态优先级和进程交互性的函数关系计算而来。 effective_prio()函数可以返回一个进程的动态优先级。这个函数以nice值为基数再加上-5到5之间的进程交互性的奖励或罚分。交互性很强的进程可以认为是I/O消耗型加上的值为负数优先级会变高很弱可以认为是处理器消耗型加上的值为正数优先级会变高。调度程序根据进程休眠的时间长短来推断进程是I/O消耗型还是处理器消耗型。 为了支持这种推断机制Linux用一个变量记录一个进程用于休眠和用于执行的时间。该变量是task_struct的sleep_avg它的范围是0到MAX_SLEEP_AVG默认值是10毫秒。当一个进程从休眠状态恢复到执行状态时sleep_arg会根据它休眠时间的长短而增加直到达到MAX_SLEEP_AVG为至。相反进程每运行一个时钟节拍sleep_avg就做相应的递减到0为止。 sleep_avg的计算不仅仅根据休眠时间的长短而且运行时间的长短也要被计算进去。如果一个进程开始占用大量的处理器时间那么它很快就会失去增加得到的优先级提升。由于奖励和罚分都加在作为基数的nice值上所以用户还是可以通过改变进程的nice值来对调度程序施加影响。 在一个进程创建的时候新建的子进程和父进程均分父进程剩余的进程时间片。这样分配是为了防止不断创建新进程来获取时间片。当一个任务的时间用完之后可以用task_timeslice()为给定任务计算一个新的时间。时间片的计算只需要把优先级按比例缩放。进程的优先级越高它每次执行得到的时间片越长。 调度程序还提供了另外一种机制来支持交换进程如果一个进程的交互性非常强那么当它的时间片用完后它会被再放置到活动数组而不是过期数组中。 一般进程在用完它们的时间片后都会被移至过期数组当活动数组没有剩余进程的时候这两个数组就会被交换活动数组变成过期数组过期数组替代活动数组。这种操作提供了时间复杂度为0(1)的时间片重新计算。将 交互式强的进程重新插入到活动数组该进程不会被立即执行它会和优先级相同的进程轮流被调度和执行。将交互性非常强的进程插入到活动数组的逻辑过程在scheduler_tick ()中实现该函数会被中断定时器调用。 睡眠和唤醒 休眠被阻塞的进程处于一个特殊的不可执行状态为了等待一些事件的发生。 休眠有两种相关的进程状态TASK_INTERRUPTIBLE和TASK_UNINTERRUPIBLE。它们唯一区别是处于TASK_UNINTERRUPIBLE的进程会忽略信号而处于TASK_INTERRUPTIBLE状态的进程如果接收到一个信号会被提前唤醒并响应该信号。两种状态的进程位于同一个等待队列上等待某些事件。 等待队列是由等待某些事件发生的进程组成的简单链表。内核用wake_queue_head_t来代表等待队列。等待队列可以通过DECLARE_WAITQUEUE()静态创建也可以用init_waitqueue_head()动态创建。进程把自己放入等待队列中并设置成不可执行状态。当与等待队列相关的事件发生的时候队列上的进程会被唤醒。 进程通过执行下面几个步骤将自己加入到一个等待队列中 调用DECLRE_WAITQUEUE()创建一个等待队列的项调用add_wait_queue()把自己将入到等待队列中。该队列会在进程等待的条件满足时唤醒它。将进程的状态变更为TASK_INTERRUPTIBLE或TASK_UNINTERRUPTIBLE如果状态被置为TASK_INTERRUPTIBLE则信号满足会唤醒进程。检查条件是否为真如果为真的话就没必要休眠了。如果不为真调用schedule()当进程被唤醒的时候它会再次检查条件是否为真如果是他就退出循环如果不是它再次调用schedule()并一直重复这步操作。当条件满足后进程将自己设置为TASK_RUNNING并调用remove_wait_queue()把自己移出等待队列。 唤醒操作通过函数wake_up()进行它会唤醒指定的等待队列上的所有进程。它调用函数try_to_wake_up()该函数负责将进程设置为TASK_RUNNING状态调用activate_task()将此进程放入可执行队列如果被唤醒的进程优先级比当前正在执行的进程的优先级高还要设置need_resched标志。 关于休眠有一点要注意存在虚假的唤醒。有时候进程被唤醒并不是因为它所等待的条件达成了所以才需要一个循环处理来保证它等待的条件真正达成。 负载平衡程序 Linux的调度程序为对称多处理系统的每个处理器准备了单独的可执行队列和锁。每个处理器都有一个自己的进程链表而它只对属于自己的这些进程进行调度操作。当可执行队列间出现负载不均衡的情况时比如一个处理器的队伍上有五个进程而另外一个处理器的队列上只有一个进程这时候就需负载平衡程序解决它负责保证可执行队列之间的负载处于均衡状态。负责平衡程序会拿当前处理器的可执行队列和系统中的其他可执行队列做比较。如果它发生了不均衡就会把相对繁忙的队列中的进程抽到当前的可执行队列中来使它们大致持平。 负载平衡程序由kernel/sched.c中的函数load_balance()来实现。它有两种调用方法。在schedule()执行的时候只要当前的可执行队列为空它就会被调用。此外它还会被定时器调用系统空闲时每隔一毫秒调用一次或者在其他情况下每隔200毫秒调用一次。在单处理器系统中load_balance不会被调用它甚至不会被编译进内核。因为那里面只有一个可执行队列因此根本没有平衡负载的必要。 负载平衡程序调用时需要锁住当前处理器的可执行队列并且屏蔽中断以避免可执行队列被并发地访问 load_balance()操作步骤 /** Check this_cpu to ensure it is balanced within domain. Attempt to move* tasks if there is an imbalance.** Called with this_rq unlocked.*/ static int load_balance(int this_cpu, runqueue_t *this_rq,struct sched_domain *sd, enum idle_type idle) {struct sched_group *group;runqueue_t *busiest;unsigned long imbalance;int nr_moved;spin_lock(this_rq-lock);schedstat_inc(sd, lb_cnt[idle]);group find_busiest_group(sd, this_cpu, imbalance, idle);if (!group) {schedstat_inc(sd, lb_nobusyg[idle]);goto out_balanced;}busiest find_busiest_queue(group);if (!busiest) {schedstat_inc(sd, lb_nobusyq[idle]);goto out_balanced;}/** This should be impossible, but since load* balancing is inherently racy and statistical,* it could happen in theory.*/if (unlikely(busiest this_rq)) {WARN_ON(1);goto out_balanced;}schedstat_add(sd, lb_imbalance[idle], imbalance);nr_moved 0;if (busiest-nr_running 1) {/** Attempt to move tasks. If find_busiest_group has found* an imbalance but busiest-nr_running 1, the group is* still unbalanced. nr_moved simply stays zero, so it is* correctly treated as an imbalance.*/double_lock_balance(this_rq, busiest);nr_moved move_tasks(this_rq, this_cpu, busiest,imbalance, sd, idle);spin_unlock(busiest-lock);}spin_unlock(this_rq-lock);if (!nr_moved) {schedstat_inc(sd, lb_failed[idle]);sd-nr_balance_failed;if (unlikely(sd-nr_balance_failed sd-cache_nice_tries2)) {int wake 0;spin_lock(busiest-lock);if (!busiest-active_balance) {busiest-active_balance 1;busiest-push_cpu this_cpu;wake 1;}spin_unlock(busiest-lock);if (wake)wake_up_process(busiest-migration_thread);/** Weve kicked active balancing, reset the failure* counter.*/sd-nr_balance_failed sd-cache_nice_tries;}/** We were unbalanced, but unsuccessful in move_tasks(),* so bump the balance_interval to lessen the lock contention.*/if (sd-balance_interval sd-max_interval)sd-balance_interval;} else {sd-nr_balance_failed 0;/* We were unbalanced, so reset the balancing interval */sd-balance_interval sd-min_interval;}return nr_moved;out_balanced:spin_unlock(this_rq-lock);/* tune up the balancing interval */if (sd-balance_interval sd-max_interval)sd-balance_interval * 2;return 0; }首先load_balance调用find_busiest_queue()找到最繁忙的可执行队列。如果没有那个可执行队列中进程的数目比当前队列中的数目多个25%或25%以上find_busiest_queue()返回NULL并且load_balance()也返回。否则最繁忙的可执行队列就被返回。其次load_balance()从最繁忙的运行队列中选择一个优先级数组以便抽取进程接着load_balance()寻找到含有进程并且优先级最高的链表因为把优先级高的进程平均分散开来才是最重要的。分析找到的所有这些优先级相同的进程选择一个不是正在执行也不会因为处理器相关性不可移动并且不在高速缓存中的进程如果有进程满足这些条件调用pull_task()将其从最繁忙的队列中抽取到当前队列。只要可执行队列之间仍然不均衡就重复上面步骤继续冲繁忙的队列中抽取进程到当前队列。这终将消除不平衡此时解除对当前运行队列的锁定从load_balance返回。 3 抢占和上下文切换 上下文切换也就是从一个可执行进程切换到另一个可执行进程由定义在kernel/sched.c中的context_switch()函数负责处理。每当一个新的进程被选出来准备投入运行的时候schedule就会调用该函数。它完成了两项基本的工作 调用定义在include/asm-具体架构/mmu_context.h中的switch_mm()该函数负责把虚拟内存从上一个进程映射切换到新进程中调用定义在include/asm-具体架构/system.h中的switch_to()该函数负责从上一个进程的处理器切换到新进程的处理器状态。 内核必须知道什么时候调用schedule()。内核提供了一个need_resched标志来表明是否需要重新执行一次调度。 每个进程都包含一个need_resched标志这是因为访问进程描述符内的数值要比访问一个全局变量快因为current宏速度很快并且描述符通常都在高速缓存中。在2.2以前的内核版本中该标志是一个全局变量。2.2到2.4版本内核中它在task_struct中。而在2.6中它被移到thread_info结构体中用一个特别的标志变量中的一位来表示。 用户抢占 用户抢占就是一个运行在用户空间的进程被另一个进程抢占执行。 内核即将返回用户空间的时候如果need_resched标志被设置会导致schedule()被调用此时就会发生用户抢占。在内核返回用户空间时它知道自己是安全的因为它可以去继续去执行当前进程那么它当然可以选择一个新的进程去执行所以内核无论是在从中断处理程序还是在系统调用后返回都会检查need_resched标志。 简而言之用户抢占在以下情况时发生 从系统调用返回用户空间从中断处理程序返回用户空间 内核抢占 内核抢占就是指一个在内核态运行的进程, 可能在执行内核函数期间被另一个进程取代。 在2.6版本的内核中内核引入了抢占能力。现在只要重新调度是安全的那么内核就可以在任何时间抢占正在执行的任务。 什么时候重新调度才是安全的呢只要没有持有锁内核就可以进行抢占。为了支持内核抢占每个进程的thread_info结构引入了preempt_count计数器。该计数器初始值为0每当使用锁的时候数值加1释放锁的时候数值减一。当数值为0的时候内核就可执行抢占。从中断返回内核空间的时候内核会检查need_resched和preempt_count的值。如果need_resched被设置并且preempt_count为0的话这说明有一个更为重要的任务需要执行并且可以安全抢占此时调度程序就会被调用。 如果内核中的进程被阻塞了或它显示地调用了schedule()内核抢占也会显式的发生。这种形式的内核抢占从来都是受支持的因为无需保证内核可以安全地被抢占。 内核抢占发生在 当从中断处理程序正在执行且返回内核空间之前当内核代码再一次具有可抢占性的时候如果内核中的任务显示的调用schedule()如果内核中的任务阻塞 4 实时 Linux提供了两种实时调度策略SCHED_FIFO和SCHED_RR。而普通的非实时的调度策略是SCHED_NORMAL。SCHED_FIFO实现了一种简单的、先进先出的调度算法它不使用时间片。SCHED_FIFO级的进程会比任何SCHED_NORMAL级的进程都先得到调度。 一旦一个SCHED_FIFO级进程处于可执行状态就会一直执行直到它自己受阻塞或显式释放处理器或者由被其他进程抢占只有较高优先级的SCHED_FIFO或SCHED_RR任务才能抢占SCHED_FIFO任务。 SCHED_RR与SCHED_FIFO大体相同只是SCHED_RR级的进程在耗尽事先分配给他的时间后就不能接着执行了。也就说SCHED_RR是有时间片的。当SCHED_RR任务耗尽它的时间片在同一优先级的其他实时进程被轮流调度。 这两种实时算法实现的都是静态优先级。内核不为实时进程计算动态优先级。这能确保给定优先级别的实时进程总能抢占优先级比它低的进程。 实时优先级范围是从0到MAX_RT_PRIO减1.默认情况下MAX_RT_PRIO为100。SCHED_NORMAL级进程的nice值共享了这个取值空间它的取值范围是从MAX_RT_PRIO到MAX_RT_PRIO40。也就说在默认情况下nice值从-20到19直接对应的是从100到139的实时优先级范围。 5 与调度相关的系统调用 Linux提供了一族系统调用用于管理与调度程序相关的参数。这些系统调用可以用来操作和处理进程优先级、调度策略及处理器同时还提供了显式的将处理器交给其他进程的机制。我们在man帮助文档上可以查找 与调度策略和优先级相关的系统调用 sched_setscheduler()和sched_getscheduler()分别用于设置和获取进程的调度策略和实时优先级它们的作用是读取或改写进程描述符task_struct的polucy和rt_priority的值。 sched_setparam()和sched_getparam()分别用于设置和获取进程的实时优先级。这两个系统调用获取封装在sched_param特殊结构体中的rt_priority。sched_get_prioruty_max()和sched_get_priority_min()分别用于返回给定调度策略的最大和最小优先级。 对于一个普通的进程nice()函数可以将给定进程的静态优先级增加一个给定的量。只有超级用户才能调用它时使用负值从而提高进程的优先级。nice()函数会调用内核的set_user_nice()函数这个函数会设置进程的task_struct的static_prio和prio值。 与处理器绑定有关的系统调用 Linux调度程序提供强制的处理器绑定机制。也就是说允许用户强制指定“这个进程无论如何都必须在这些处理器上运行”。这种强制的亲和性保存在进程task_struct的cpus_allowed这个位掩码标志中。该掩码标志的每一位对应一个系统可用的处理器。默认情况下所有的位都被设置进程可以在系统中所有可用的处理器上执行。用户可以用sched_setaffinity函数设置一个不同一个或几个位组合的位掩码。而调用sched_getaffinity函数则返回当前的cpus_allowed位掩码。 子进程继承父进程进程描述符的cpus_allowed。如果父进程运行在指定的处理器上子进程也会运行在该处理器上。 放弃处理器时间 Linux通过sched_yield函数系统调用来将处理器让给其他等待执行的进程。它是通过将进程从活动队列移到过期队列实现的。由于实时进程不会过期所以属于例外实时进程只被移动到其优先级队列的最后面不会放到过期队列中。 内核代码为了方便可以直接调用yield()它先要确定给定进程确实处于可执行状态然后再调用sched_yield函数。用户空间的应用程序直接使用sched_yield()系统调用就可以了。 6 调度程序小结 本章介绍了进程调度所遵循的基本原理、具体实现、调度算法以及目前Linux内核使用的借口。
http://www.pierceye.com/news/549370/

相关文章:

  • 电商购物网站m3u8插件 wordpress
  • 河北手机网站制作多少钱wordpress文章头部
  • 悠悠我心的个人网站素材网站建设教育培训
  • 网站建设定金做什么会计分录湘潭有实力的关键词优化公司
  • 网站备案 网站建设方案书云搜索app
  • 青岛网络推广建站民营医院建设网站
  • 罗湖住房和建设局网站wordpress调用内容代码
  • 网络logo设计优化设计七年级下册语文答案
  • 贵港网站seo安新网站建设
  • 网站怎么自己编辑模块创意网名大全
  • php的网站架构建设框架wordpress如何运行
  • 广州seo网站排名优化数码设计网站
  • 免费做视频相册的网站网站建设的功能描述
  • 网站建设方案浩森宇特alexa排名是什么意思
  • 网上手机网站建设计划书百度小说风云榜排名
  • 用js来做网站帝国cms这么做网站
  • 网站建设需求分析班级网站备案服务类型
  • 网站备案幕布照片怎么算合格北京专业网站开发
  • 浙江建设职业技术学院塘栖校区网站网络推广方法有几种
  • 呢图网站场建设封面长安镇做网站
  • 搜索关键词的网站黄山做网站
  • 网络建站系统去除wordpress主题头部作者信息
  • 鼓楼微网站开发番禺有经验的网站建设
  • 对网站建设心得进入公众号继续阅读怎么弄
  • 网站建设公司投诉电话可以先做网站后备案吗
  • 顺的品牌网站设计价位网站开发合同书
  • 用html5制作个人网站深圳百度国际大厦
  • 网络网站公司网站管理平台扩展插件
  • 个人小说网站怎么做把自己做的网页变成网站
  • led网站制作网站登录后不显示内容