sched_yield()和nanosleep()对进程调度的影响
关键词: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()对进程调度的影响的更多相关文章
- 《Linux/Unix系统编程手册》 时间子系统
Linux下操作系统编程有两本经典APUE即<Advanced Programming in the UNIX Environment>和TLPI<The Linux Program ...
- 20135202闫佳歆--week 9 期中总结
期中总结 前半学期的主要学习内容是学习mooc课程<Linux内核分析>以及课本<Linux内核设计与实现>. 所涉及知识点总结如下: 1. Linux内核启动的过程--以Me ...
- 一种基于PTP 协议的局域网高精度时钟同步方法(转)
原文地址 http://www.dzsc.com/data/html/2011-1-17/88338.html 1 引言 在分布式系统中, 常常需要一个全局时间, 用来确定系统中各种事件发生的先后.协 ...
- Linux进程管理 (9)实时调度类分析,以及FIFO和RR对比实验
关键词:rt_sched_class.SCHED_FIFO.SCHED_RR.sched_setscheduler().sched_setaffinity().RR_TIMESLICE. 本文主要关注 ...
- 8、Linux设备驱动的并发控制
一.并发与竞争 并发是指多个 多个执行单元同时执行,而这对对共享的资源,比如硬件的资源.软件的全局变量.静态变量 的访问,很容易导致竞态, 1.1.中断屏蔽 在单核的 CPU 里,避 ...
- java web学习总结(二十六) -------------------JSP属性范围
所谓的属性范围就是一个属性设置之后,可以经过多少个其他页面后仍然可以访问的保存范围. 一.JSP属性范围 JSP中提供了四种属性范围,四种属性范围分别指以下四种: 当前页:一个属性只能在一个页面中取得 ...
- javaweb学习总结(十八)——JSP属性范围
所谓的属性范围就是一个属性设置之后,可以经过多少个其他页面后仍然可以访问的保存范围. 一.JSP属性范围 JSP中提供了四种属性范围,四种属性范围分别指以下四种: 当前页:一个属性只能在一个页面中取得 ...
- Linux进程调度
原文地址: http://cchxm1978.blog.163.com/blog/static/35428253201092910491682/ 相当不错的文章,读了后收藏,多谢博主分享! ----- ...
- Linux系统编程——进程调度浅析
概述 操作系统要实现多进程.进程调度不可缺少. 有人说,进程调度是操作系统中最为重要的一个部分.我认为这样的说法说得太绝对了一点,就像非常多人动辄就说"某某函数比某某函数效率高XX倍&quo ...
随机推荐
- .NET Core和无服务器框架
无服务器框架是一个云提供商无关的工具包,旨在帮助构建,管理和部署无服务器组件的操作,以实现完整的无服务器架构或不同功能即服务(FaaS).无服务器框架的主要目标是为开发人员提供一个界面,该界面抽象出云 ...
- .net core百万设备连接服务和硬件需求测试
随着物联网的普及,服务应用将面对大量物联设备处理:早期.NET在通讯上的处理能力一直给人的印像并不怎样,但net core经历过大量的优化后在各个模块的处理性能都有着比较出色的提升,针对网络方向的处理 ...
- Java题库——Chapter16 JavaFX UI组件和多媒体
Chapter 16 JavaFX UI Controls and Multimedia Section 16.2 Labeled and Label1. To create a label with ...
- 用Python6种方法:给定一个不超过5位的正整数,判断有几位
方法一:作比较 a=int(input(">>>>")) if a<10: print(1) elif a<100: #第一个条件已经过滤了大于 ...
- 使用PowerShell实现服务器常用软件的无人值守安装
操作系统:windows server 2016 , windows server 2019 软件环境: 类型 名称 版本 系统功能 TelnetClien IIS 启用Asp.n ...
- FAQ: Oracle Flex ASM 12c / 12.1 (Doc ID 1573137.1)
FAQ: Oracle Flex ASM 12c / 12.1 (Doc ID 1573137.1) APPLIES TO: Oracle Database - Enterprise Edition ...
- 不同浏览器对cookie大小与个数的限制
一.浏览器允许每个域名所包含的cookie数: Microsoft指出InternetExplorer8增加cookie限制为每个域名50个,但IE7似乎也允许每个域名50个cookie. Firef ...
- Iris入门操练1
选一个框架,慢慢熟悉··· 按官网文档,先走一次.. package main import ( "github.com/kataras/iris/v12" "githu ...
- git结合项目基本使用
学习博客:1,史上最浅显易懂的Git教程! 2,结合项目具体使用 3,常用命令快速查看 4,git stash 用法总结和注意点 一.git的工作原理和工作流程 Workspace:工作区 Index ...
- 【模板】分治 FFT
Link Solution 有两种解法. 法1: 直接上分治FFT,也就是CDQ分治+FFT. 具体做法是先递归左半边,算出左半边答案之后,将左半边贡献到右半边,然后递归右半边. 分治是一个log的, ...