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 ...
随机推荐
- Linux selinux 规则导致audit拒绝
Linux selinux 规则导致audit拒绝 转载注明来源: 本文链接 来自osnosn的博客,写于 2019-09-26. 查看 audit2why -d audit2allow 这两个命令. ...
- Hive初步认识,理解Hive(一)
Hive初步认识,理解Hive(一) 用了有一段时间的Hive了,之前一直以为hive是个数据库,类似Mysql.Oracle等数据库一样,其实不然. Hive是实现Hadoop 的MapReduce ...
- Java 9 ← 2017,2019 → Java 13,来看看Java两年来的变化
距离 2019 年结束,只剩下 33 天了.你做好准备迎接 2020 年了吗? 一到年底,人就特别容易陷入回忆和比较之中,比如说这几天的对比挑战就火了! 这个话题登上了微博的热搜榜,也刷爆了朋友圈, ...
- sap-abap 权限控制
FORM AUTH_CHECK . "工厂 LOOP AT S_WERKS. AUTHORITY-CHECK OBJECT 'M_BANF_WRK' ID 'WERKS' FIELD S_W ...
- maven搭建webservice apache cxf实现
用 web方式发布 webService 服务端.客户端 一.服务器端搭建 1.首先创建 一个web工程(增加Maven依赖) 2.增加Maven依赖包,如下: <project xmlns=& ...
- java后台树形结构展示---懒加载
一.数据库设计 二.实体类:entity import com.joyoung.cloud.security.common.validatedGroup.Add;import com.joyoung. ...
- Axure制作dialog效果的动作步骤
1.在Axure中添加一个弹框按钮 2.将动态面版拖动到界面中 3.双击动态面版,双击state 4.拖入一块图片占位符进来 5.设置图片 6.回到上一个界面设置动态面版的大小,使其 ...
- Kali Linux configuration "Ettercap"
Xx_Instroduction Ettercap is a man-in-the-middle attack(MITM) tool,kali take this tool,so,use front ...
- Android五大布局详解——GridLayout(网格布局)
GridLayout 本章以一个小的实现示例讲述: 实现效果如图: 代码实现: <?xml version="1.0" encoding="utf-8"? ...
- jQuery - 拦截所有Ajax请求(统一处理超时、返回结果、错误状态码 )
样例代码: <html> <head> <title>hangge.com</title> <meta charset="utf-8&q ...