- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我写了一个 c 程序来测试 linux 调度器。这是我的代码:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
void Thread1()
{
sleep(1);
int i,j;
int policy;
struct sched_param param;
pthread_getschedparam(pthread_self(),&policy,¶m);
if(policy == SCHED_OTHER)
printf("SCHED_OTHER\n");
if(policy == SCHED_RR)
printf("SCHED_RR 1 \n");
if(policy==SCHED_FIFO)
printf("SCHED_FIFO\n");
/* for(i=1;i<100;i++) */
while(1)
{
for(j=1;j<5000000;j++)
{
}
printf("thread 1\n");
}
printf("Pthread 1 exit\n");
}
void Thread2()
{
sleep(1);
int i,j,m;
int policy;
struct sched_param param;
pthread_getschedparam(pthread_self(),&policy,¶m);
if(policy == SCHED_OTHER)
printf("SCHED_OTHER\n");
if(policy == SCHED_RR)
printf("SCHED_RR\n");
if(policy==SCHED_FIFO)
printf("SCHED_FIFO\n");
/* for(i=1;i<10;i++) */
while(1)
{
for(j=1;j<5000000;j++)
{
}
printf("thread 2\n");
}
printf("Pthread 2 exit\n");
}
void Thread3()
{
sleep(1);
int i,j;
int policy;
struct sched_param param;
pthread_getschedparam(pthread_self(),&policy,¶m);
if(policy == SCHED_OTHER)
printf("SCHED_OTHER\n");
if(policy == SCHED_RR)
printf("SCHED_RR \n");
if(policy==SCHED_FIFO)
printf("SCHED_FIFO\n");
/* for(i=1;i<10;i++) */
while(1)
{
for(j=1;j<5000000;j++)
{
}
printf("thread 3\n");
}
printf("Pthread 3 exit\n");
}
int main()
{
int i;
i = getuid();
if(i==0)
printf("The current user is root\n");
else
printf("The current user is not root\n");
pthread_t ppid1,ppid2,ppid3;
struct sched_param param;
pthread_attr_t attr3,attr1,attr2;
pthread_attr_init(&attr1);
pthread_attr_init(&attr3);
pthread_attr_init(&attr2);
param.sched_priority = 97;
pthread_attr_setschedpolicy(&attr1,SCHED_RR);
pthread_attr_setschedparam(&attr1,¶m);
pthread_attr_setinheritsched(&attr1,PTHREAD_EXPLICIT_SCHED);
param.sched_priority = 98;
pthread_attr_setschedpolicy(&attr2,SCHED_RR);
pthread_attr_setschedparam(&attr2,¶m);
pthread_attr_setinheritsched(&attr2,PTHREAD_EXPLICIT_SCHED);
pthread_create(&ppid3,&attr3,(void *)Thread3,NULL);
pthread_create(&ppid2,&attr2,(void *)Thread2,NULL);
pthread_create(&ppid1,&attr1,(void *)Thread1,NULL);
pthread_join(ppid3,NULL);
pthread_join(ppid2,NULL);
pthread_join(ppid1,NULL);
pthread_attr_destroy(&attr2);
pthread_attr_destroy(&attr1);
return 0;
}
在这个程序中,我创建了一个具有默认属性的线程和两个调度策略为 SCHED_RR 和特定优先级的线程。我的问题是:当我运行程序时,我几乎看不到线程 1 的输出。这是怎么发生的? 我认为线程 1 和线程 2 是实时进程,线程 3 是正常进程。因此线程 3 永远不会运行,直到线程 1 和线程 2 退出。但是在我的程序线程 1 和线程 2 永不退出,所以我预计只有线程 2 可以实际运行。 为什么我能看到线程2和线程3的输出,而看不到线程1的输出?
最佳答案
线程 3 可以运行,因为 0.05s 是为非运行时任务预留的,通过 echo -1 >/proc/sys/kernel/sched_rt_runtime_us
禁用它:
The default values for
sched_rt_period_us
(1000000 or 1s) andsched_rt_runtime_us
(950000 or 0.95s). This gives 0.05s to be used bySCHED_OTHER
(non-RT tasks). These defaults were chosen so that a run-away realtime tasks will not lock up the machine but leave a little time to recover it. By setting runtime to -1 you'd get the old behaviour back.
线程 1 无法运行,因为线程 2 具有更高的优先级(注意 99 是 pthread 调用中的最高 RT 优先级,这与 Linux 内部编号矛盾并解释为 here ),并且循环调度仅在具有相同优先级的进程队列:
SCHED_RR
tasks are scheduled by priority, and within a certain priority they are scheduled in a round-robin fashion. EachSCHED_RR
task within a certain priority runs for its allotted timeslice, and then returns to the bottom of the list in its priority array queue.
Understanding the Linux 2.6.8.1 CPU Scheduler
关于如何找出发生这种情况的原因的一些说明。为此,我们需要源代码和动态跟踪器,如 SystemTap。切换线程(或者更准确地说上下文切换)can be traced通过 scheduler.ctxswitch
探测器,它是 sched_switch
跟踪点的包装器。
检查跟踪点周围的源代码表明新任务由调用 pick_next_task
的 __schedule
函数处理:
3392 next = pick_next_task(rq, prev, cookie);
...
3397 if (likely(prev != next)) {
...
3402 trace_sched_switch(preempt, prev, next);
爬取源代码将我们引导至 pick_next_task_rt
,它在特定条件下返回 NULL 而不是我们的线程。 SystemTap 时间到了!
# stap -e 'probe kernel.function("pick_next_task_rt").return {
if ($return == 0) {
println($rq->rt$) } }' -c ./a.out
...
{.active={...}, .rt_nr_running=2, .highest_prio={...}, .rt_nr_migratory=2, .rt_nr_total=2,
.overloaded=1, .pushable_tasks={...}, .rt_throttled=1, .rt_time=950005330, .rt_runtime=950000000,
.rt_runtime_lock={...}, .rt_nr_boosted=0, .rq=0xffff8801bfc16c40,
.leaf_rt_rq_list={...}, .tg=0xffffffff81e3d480}
SCHED_OTHER
因此,当我们切换到 SCHED_OTHER
时,rt_time
似乎大于 950 毫秒并且设置了 rt_throttled
标志。进一步谷歌搜索导致 this answer和上面链接的文档。
关于c - 在linux中,为什么一个正常的进程仍然可以运行,而实时进程却不退出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46262490/
Closed. This question is opinion-based。它当前不接受答案。 想改善这个问题吗?更新问题,以便editing this post用事实和引用来回答。 2年前关闭。
我想显示我的网站上所有用户都在线(实时;就像任何聊天模块一样)。我正在使用下面提到的脚本来执行此操作。 HTML: Javascript: var doClose = false; documen
有什么方法可以知道 Algolia 何时成功处理了排队作业,或者与上次重新索引相比,Algolia 是否索引了新文档? 我们希望建立一个系统,每当新文档被索引时,浏览网站的用户都会收到实时更新警告,并
构建将在“桌面”而不是浏览器中运行的 Java 应用程序的推荐策略是什么。该应用程序的特点是: 1. Multiple application instances would be running o
这是场景: 我正在编写一个医疗相关程序,可以在没有连接的情况下使用。当采取某些措施时,程序会将时间写入CoreData记录。 这就是问题所在,如果他们的设备将时间设置为比实际时间早的时间。那将是一个大
我有: $(document).ready(function () { $(".div1, .div2, .div3, .div4, .div5").draggable();
我有以下 jquery 代码: $("a[id*='Add_']").live('click', function() { //Get parentID to add to. var
我有一个 jsp 文件,其中包含一个表单。提交表单会调用处理发送的数据的 servlet。我希望当我点击提交按钮时,一个文本区域被跨越并且应该实时显示我的应用程序的日志。我正在使用 Tomcat 7。
我编辑了我的问题,我在 Default.aspx 页面中有一个提交按钮和文本框。我打开两个窗口Default.aspx。我想在这个窗口中向文本框输入文本并按提交,其他窗口将实时更新文本框。 请帮助我!
我用 php 创建了一个小型 CMS,如果其他用户在线或离线,我想显示已登录的用户。 目前,我只创建一个查询请求,但这不会一直更新。我希望用户在发生某些事情时立即看到更改。我正在寻找一个类似于 fac
我有以下问题需要解决。我必须构建一个图形查看器来查看海量数据集。 我们有一些特定格式的文件,其中包含数百万条代表实验结果的记录。每条记录代表大图上的一个样本点。我见过的最大的文件有 4370 万条记录
我最近完成了申请,但遇到了一个大问题。我一次只需要允许 1 个用户访问它。每个用户每次都可以访问一个索引页面和“开始”按钮。当用户点击开始时,应用程序锁定,其他人需要等到用户完成。当用户关闭选项卡/浏
我是 Android 开发新手。我正在寻找任何将音高变换应用到输出声音(实时)的方法。但我找不到任何起点。 我找到了这个 topic但我仍然不知道如何应用它。 有什么建议吗? 最佳答案 一般来说,该算
背景 用户计算机上的桌面应用程序从调制解调器获取电话号码,并在接到电话后将其发送到 PHP 脚本。目前,我可以通过 PHP 在指定端口上接收数据/数据包。然后我有一个连接到 411 数据库并返回指定电
很抱歉提出抽象问题,但我正在寻找一些关于在循环中执行一些等效操作的应用程序类型的示例/建议/文章,并且循环的每次迭代都应该在特定时间部分公开其结果(例如, 10 秒)。 我的应用程序在外部 WCF 服
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: What specifically are wall-clock-time, user-cpu-time,
我最近遇到了一个叫做 LiveChart 的工具,决定试用一下。 不幸的是,我在弄清楚如何实时更新图表值时遇到了一些问题。我很确定有一种干净正确的方法可以做到这一点,但我找不到它。 我希望能够通过 p
我正在实现实时 flutter 库 https://pub.dartlang.org/packages/true_time 遇到错误 W/DiskCacheClient(26153): Cannot
我一直在使用 instagram 的实时推送 api ( http://instagram.com/developer/realtime/ ) 来获取特定位置的更新。我使用“半径”的最大可能值,即 5
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 7年前关闭。 Improve thi
我是一名优秀的程序员,十分优秀!