关键词: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. js中关于constructor与prototype的理解

    1.①__proto__和constructor属性是对象所独有的:② prototype属性是函数所独有的,因为函数也是一种对象,所以函数也拥有__proto__和constructor属性. 2. ...

  2. Dijkstra.NET 库体验报告

    在VS里用Nuget下载"Dijkstra.NET"库,然后就可以在需要的地方使用了. 首先,这是一个简单的graph,5个节点,7条边. 上代码 移动端看不清楚的可以看下面的: ...

  3. 网页添加Live2D看板娘简易教程

    看板娘是一种职业和习惯称呼,也是ACGN次文化中的萌属性之一.简而言之就是小店的女服务生,也有“吸引顾客,招揽生意,提高人气”等作用类似品牌形象代言人的含义. 如果想在自己的博客上放一个呆萌的看板娘非 ...

  4. python部署mariadb主从架构

    主机部署: import configparser import os def config_mariadb_yum(): exists = os.path.exists('/etc/yum.repo ...

  5. Java8特性Lambda表达式

    Lambda 表达式 简介: Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性. Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中). (parame ...

  6. pycharm中全局搜索ctrl+shift+F快捷键无反应原因和解决

    全局搜索快捷键无反应原因:搜狗输入法占用的ctrl+shift+F快捷键,简繁切换的快捷键.在搜狗输入法中将此项取消.

  7. 2019阿里天猫团队Java高级工程师面试题之第二面

    2019阿里天猫团队Java高级工程师面试题之第一面 2019阿里天猫团队Java高级工程师面试题之第三面 1.Tomcat的基本架构是什么? https://blog.csdn.net/xlgen1 ...

  8. C++如何使用宏定义来简化代码性能测试 | cpp macro like function to implement a performance profiler

    本文首发于个人博客https://kezunlin.me/post/65dc693d/,欢迎阅读最新内容! cpp macro like function to implement a perform ...

  9. DOM介绍以及使用方法

    DOM的基本讲解 一.DOM (Document Object Model)文档对象模型 1.有属性有方法 var person = { name:'派大星', fav:function(){ } } ...

  10. CSS属性继承

    在CSS中有一些属性是可以继承的,跟继承家产一样,哎,一代一代的往下传,而有些属性就比较惨了,不能继承,只能自己来设置. 我简略的总结了一下一些可以继承和不可以继承的属性 可继承 1.字体系列属性:f ...