关键词:sched_yield()、nanosleep()等等。

sched_yield()主动放弃CPU执行权,nanosleep()是睡眠一段时间后再唤醒。

1. sched_yield()实现

sched_yield()会主动放弃当前CPU给其他进程使用;但是如果当前CPU上无其他进程等待执行,则直接返回继续执行当前进程。

调用sched_yield()之后当前进程会被移动到进程优先级等待队列尾部,让相同或者更高优先级进程运行。

sched_yield()确保当前进程在资源竞争严重时,给其他进程执行机会来提高性能。

SYSCALL_DEFINE0(sched_yield)
{
struct rq *rq = this_rq_lock(); schedstat_inc(rq->yld_count);
current->sched_class->yield_task(rq); __release(rq->lock);
spin_release(&rq->lock.dep_map, , _THIS_IP_);
do_raw_spin_unlock(&rq->lock);
sched_preempt_enable_no_resched(); schedule(); return ;
} asmlinkage __visible void __sched schedule(void)
{
struct task_struct *tsk = current; sched_submit_work(tsk);
do {
preempt_disable();
__schedule(false);
sched_preempt_enable_no_resched();
} while (need_resched());
} static void __sched notrace __schedule(bool preempt)
{
struct task_struct *prev, *next;
unsigned long *switch_count;
struct pin_cookie cookie;
struct rq *rq;
int cpu;
...
next = pick_next_task(rq, prev, cookie);---------------------选择优先级最高的进程作为下一个运行进程。
clear_tsk_need_resched(prev);
clear_preempt_need_resched();
rq->clock_skip_update = ; if (likely(prev != next)) {----------------------------------如果sched_yield()后,当前进程prev即为优先级最高的进程,即prev==next。那么则不会进行进程切换操作,直接返回。
rq->nr_switches++;
rq->curr = next;
++*switch_count; trace_sched_switch(preempt, prev, next);
rq = context_switch(rq, prev, next, cookie); /* unlocks the rq */
} else {
lockdep_unpin_lock(&rq->lock, cookie);
raw_spin_unlock_irq(&rq->lock);
} balance_callback(rq);
}

对于CFS调度器类,yield_task()对应yield_task_fair()。

static void yield_task_fair(struct rq *rq)
{
struct task_struct *curr = rq->curr;
struct cfs_rq *cfs_rq = task_cfs_rq(curr);
struct sched_entity *se = &curr->se; if (unlikely(rq->nr_running == ))--------------------如果当前运行队列上仅有一个运行进程,直接返回。
return; clear_buddies(cfs_rq, se); if (curr->policy != SCHED_BATCH) {
update_rq_clock(rq); update_curr(cfs_rq); rq_clock_skip_update(rq, true);
} set_skip_buddy(se);
}

下面是系统无其他进程运行时,可以看出进程独占了CPU很长时间。只是在有其他内核线程运行后,才放弃CPU执行权。

2. nanosleep()和sched_yield()对比

2.1 while(true)尽量独占CPU

#include <iostream>
#include <chrono>
#include <thread>
#include <atomic>
#include <mutex>
#include <time.h> std::mutex g_mutex;
std::atomic<bool> ready(false); void count1m(int id)
{
while (true)
{
}
} int main()
{
std::thread threads; threads = std::thread(count1m, );
threads.join(); return ;
}

这种情况进程会尽可能独占整个CPU,但是在有竞争进程存在的时候,需要和其他进程均分CPU时间。所以出现下面每工作4ms,然后切换出去4ms时间的情况。

在没有其他进程运行的时候,可以独占CPU时间。

2.2 nanosleep()进程休眠一段时间

#include <iostream>
#include <chrono>
#include <thread>
#include <atomic>
#include <mutex>
#include <time.h> std::mutex g_mutex;
std::atomic<bool> ready(false); void count1m(int id)
{
struct timespec delay;
delay.tv_sec = ;
delay.tv_nsec = ;
while (true)
{
nanosleep(&delay, NULL);
}
} int main()
{
std::thread threads; threads = std::thread(count1m, );
threads.join(); return ;
}

间隔休眠唤醒情况下,即使系统中存在其他进程在运行,当前进程唤醒后仍然可以抢到CPU资源,sched_switch表示放入队列,sched_wakeup表示得到CPU资源,中间可能存在一定延时。

在没有其他进程情况下,能更快得到调度。

2.3 sched_yield()主动放弃

#include <iostream>
#include <chrono>
#include <thread>
#include <atomic>
#include <mutex>
#include <time.h> std::mutex g_mutex;
std::atomic<bool> ready(false); void count1m(int id)
{
while (true)
{
std::this_thread::yield();
}
} int main()
{
std::thread threads; threads = std::thread(count1m, );
threads.join(); return ;
}

这种情况和第一种区别在于,sched_yield()会主动放弃CPU执行权。第一种情况是根据CFS调度器类来分配时间;这里还结合了进程主动放弃调度的情况。

2.4 sched_yield()和nanosleep()混合使用

#include <iostream>
#include <chrono>
#include <thread>
#include <atomic>
#include <mutex>
#include <time.h> std::mutex g_mutex;
std::atomic<bool> ready(false); void count1m(int id)
{
struct timespec delay;
delay.tv_sec = ;
delay.tv_nsec = ;
while (true)
{
std::this_thread::yield();
nanosleep(&delay, NULL);
}
} int main()
{
std::thread threads; threads = std::thread(count1m, );
threads.join(); return ;
}

这种情况下sched_yield()和nanosleep()叠加使用和单独使用nanosleep()效果类似,nanosleep()本省也是主动放弃CPU使用权。

所以综合来看while(1)中使用sched_yield()要比延时的响应更及时,但是也牺牲了CPU占用率。在没有其他进程运行的情况下,sched_yield()就会一个人独占CPU资源。

sched_yield()和nanosleep()对进程调度的影响的更多相关文章

  1. 《Linux/Unix系统编程手册》 时间子系统

    Linux下操作系统编程有两本经典APUE即<Advanced Programming in the UNIX Environment>和TLPI<The Linux Program ...

  2. 20135202闫佳歆--week 9 期中总结

    期中总结 前半学期的主要学习内容是学习mooc课程<Linux内核分析>以及课本<Linux内核设计与实现>. 所涉及知识点总结如下: 1. Linux内核启动的过程--以Me ...

  3. 一种基于PTP 协议的局域网高精度时钟同步方法(转)

    原文地址 http://www.dzsc.com/data/html/2011-1-17/88338.html 1 引言 在分布式系统中, 常常需要一个全局时间, 用来确定系统中各种事件发生的先后.协 ...

  4. Linux进程管理 (9)实时调度类分析,以及FIFO和RR对比实验

    关键词:rt_sched_class.SCHED_FIFO.SCHED_RR.sched_setscheduler().sched_setaffinity().RR_TIMESLICE. 本文主要关注 ...

  5. 8、Linux设备驱动的并发控制

    一.并发与竞争     并发是指多个 多个执行单元同时执行,而这对对共享的资源,比如硬件的资源.软件的全局变量.静态变量 的访问,很容易导致竞态, 1.1.中断屏蔽     在单核的  CPU 里,避 ...

  6. java web学习总结(二十六) -------------------JSP属性范围

    所谓的属性范围就是一个属性设置之后,可以经过多少个其他页面后仍然可以访问的保存范围. 一.JSP属性范围 JSP中提供了四种属性范围,四种属性范围分别指以下四种: 当前页:一个属性只能在一个页面中取得 ...

  7. javaweb学习总结(十八)——JSP属性范围

    所谓的属性范围就是一个属性设置之后,可以经过多少个其他页面后仍然可以访问的保存范围. 一.JSP属性范围 JSP中提供了四种属性范围,四种属性范围分别指以下四种: 当前页:一个属性只能在一个页面中取得 ...

  8. Linux进程调度

    原文地址: http://cchxm1978.blog.163.com/blog/static/35428253201092910491682/ 相当不错的文章,读了后收藏,多谢博主分享! ----- ...

  9. Linux系统编程——进程调度浅析

    概述 操作系统要实现多进程.进程调度不可缺少. 有人说,进程调度是操作系统中最为重要的一个部分.我认为这样的说法说得太绝对了一点,就像非常多人动辄就说"某某函数比某某函数效率高XX倍&quo ...

随机推荐

  1. asp.net core 3.0 选项模式1:使用

    本篇只是从应用角度来说明asp.net core的选项模式,下一篇会从源码来分析 1.以前的方式 以前我们使用web.config/app.config时是这样使用配置的 var count = Co ...

  2. vue组件之间的通信方式

    组件之间的通信方式有很多种 这里分享4种组件之间的通信方式 props(主要是父传子)  自定义事件(主要是子传父)  pubsub消息订阅与发布  xuex 1.props和自定义事件 app.vu ...

  3. Prometheus学习系列(六)之Prometheus 查询说明

    前言 本文来自Prometheus官网手册和 Prometheus简介 Prothetheus查询 Prometheus提供一个函数式的表达式语言PromQL (Prometheus Query La ...

  4. HALCON数据类型和C#对应数据类型的对比

    摘要:HALCON数据类型:Iconic Variables(图形变量).Control Variables(控制变量).在C#中,图形变量用HObject声明,控制变量用HTuple声明.(halc ...

  5. HTML基础——基础标签

    一.HTML概述 htyper text markup language  即超文本标记语言. 超文本: 就是指页面内可以包含图片.链接,甚至音乐.程序等非文字元素. 标记语言: 标记(标签)构成的语 ...

  6. 从零开始学vuejs

    最近一段时间都花在了学习vue上,还总是断断续续的,学习的效果不是很明显,思考了好久了,应该是没有进行一个系统的总结,导致很多知识点总是似是而非,而且也有一部分是思维还没有从java转变过来,废话不多 ...

  7. 004.Windows Server 故障转移群集 (WSFC)简介

    一 WSFC 简介 1.1 WSFC 概述 “Windows Server 故障转移群集”(WSFC) 群集是一组独立的服务器,它们共同协作以提高应用程序和服务的可用性.SQL Server 2012 ...

  8. 今日资源帖-PPT逆袭秘籍72集+2000套模板,太经典了

    好资源不私藏,分享是一种态度 今日给大家分享的是PPT教程和2000套模板 如何让PPT成为你职场的利器 如何让你的PPT更具表现力 2000套模板随便选 PPT视频教程 链接 https://pan ...

  9. Java IO系列之 ByteArrayInputStream

    http://www.cnblogs.com/skywang12345/p/io_02.html

  10. Flink概述| 配置

    流处理技术的演变 在开源世界里,Apache Storm项目是流处理的先锋.Storm提供了低延迟的流处理,但是它为实时性付出了一些代价:很难实现高吞吐,并且其正确性没能达到通常所需的水平,换句话说, ...