Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SCHED_IDLE是否实际上排除了在非空闲内核上执行?_C_Linux_Pthreads_Posix_Priority Inversion - Fatal编程技术网

SCHED_IDLE是否实际上排除了在非空闲内核上执行?

SCHED_IDLE是否实际上排除了在非空闲内核上执行?,c,linux,pthreads,posix,priority-inversion,C,Linux,Pthreads,Posix,Priority Inversion,我正在尝试使用SCHED_IDLE,为没有优先级继承互斥体的无限优先级反转实现一个非特权测试用例。该测试使用SCHED_FIFO和不同的实时优先级(非PI互斥锁死锁,使用PI互斥锁立即解决),但要将其包含在将在没有实时权限的情况下运行的测试集中,我想使用SCHED_IDLE来代替,使用“中”和“高”优先级线程都是SCHED_OTHER(在这种情况下,它不是真正的优先级“反转”,但这个概念应该仍然有效——“中”线程应该排除“低”线程的执行) 不幸的是,测试无法区分PI和非PI互斥体;无论哪种方式,

我正在尝试使用
SCHED_IDLE
,为没有优先级继承互斥体的无限优先级反转实现一个非特权测试用例。该测试使用
SCHED_FIFO
和不同的实时优先级(非PI互斥锁死锁,使用PI互斥锁立即解决),但要将其包含在将在没有实时权限的情况下运行的测试集中,我想使用
SCHED_IDLE
来代替,使用“中”和“高”优先级线程都是
SCHED_OTHER
(在这种情况下,它不是真正的优先级“反转”,但这个概念应该仍然有效——“中”线程应该排除“低”线程的执行)

不幸的是,测试无法区分PI和非PI互斥体;无论哪种方式,它都会取得进步。显然,即使存在另一个可运行的任务,
SCHED_IDLE
任务仍在运行。CPU亲缘关系已设置为将它们都绑定到同一个内核,以便低优先级任务不能迁移到其他内核运行。我知道
SCHED_IDLE
任务应该在内核空间中以提升的权限运行,以防止内核空间优先级反转,因此我尝试通过在用户空间中使“low”线程繁忙循环来确保它不会进入内核空间,而且
strace
没有显示它在不应该向前推进的时间内进行系统调用的迹象

Linux的
SCHED_IDLE
是否只允许在内核没有实际空闲时运行空闲任务?或者我可能还遗漏了什么

这是测试代码,稍作修改,以便可以在实时模式或
SCHED_IDLE
模式下运行:

#define _GNU_SOURCE
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <semaphore.h>

sem_t sem;

void *start1(void *p)
{
    pthread_mutex_lock(p);
    sem_post(&sem);
    sem_post(&sem);
    usleep(100000);
    pthread_mutex_unlock(p);
    return 0;
}

void *start2(void *p)
{
    sem_wait(&sem);
    time_t t0 = time(0);
    while (pthread_mutex_trylock(p)) {
        if (time(0)>t0+5) return 0;
    }
    pthread_mutex_unlock(p);
    return 0;
}

void *start3(void *p)
{
    sem_wait(&sem);
    struct timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);
    ts.tv_sec += 5;
    int r;
    if (r=pthread_mutex_timedlock(p, &ts)) {
        printf("failed: %d %s\n", r, strerror(r));
    } else {
        pthread_mutex_unlock(p);
    }
    return 0;
}

int main(int argc, char **argv)
{
    int policy = argc>1 ? SCHED_IDLE : SCHED_FIFO;
    int a = sched_get_priority_min(policy);
    pthread_attr_t attr;
    pthread_t t1,t2,t3;
    struct sched_param param = {0};

    cpu_set_t set = {0};
    CPU_ZERO(&set);
    CPU_SET(0, &set);
    pthread_setaffinity_np(pthread_self(), sizeof set, &set);

    pthread_attr_init(&attr);
    pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
    pthread_attr_setschedpolicy(&attr, policy);

    pthread_mutexattr_t ma;
    pthread_mutexattr_init(&ma);
    pthread_mutexattr_setprotocol(&ma, PTHREAD_PRIO_INHERIT);
    pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK);
    pthread_mutex_t mtx;
    pthread_mutex_init(&mtx, &ma);

    sem_init(&sem, 0, 0);

    param.sched_priority = a+1;
    pthread_attr_setschedparam(&attr, &param);
    if (pthread_create(&t2, policy==SCHED_IDLE ? 0 : &attr, start2, &mtx)) return 1;

    param.sched_priority = a+2;
    pthread_attr_setschedparam(&attr, &param);
    if (pthread_create(&t3, policy==SCHED_IDLE ? 0 : &attr, start3, &mtx)) return 1;

    param.sched_priority = a;
    pthread_attr_setschedparam(&attr, &param);
    if (pthread_create(&t1, &attr, start1, &mtx)) return 1;

    pthread_join(t1, 0);
    pthread_join(t2, 0);
    pthread_join(t3, 0);
    return 0;
}
定义GNU源
#包括
#包括
#包括
#包括
#包括
#包括
#包括
扫描电镜;
void*start1(void*p)
{
pthread_mutex_lock(p);
sem_post(和sem);
sem_post(和sem);
美国LEEP(100000);
pthread_mutex_unlock(p);
返回0;
}
void*start2(void*p)
{
sem_wait(&sem);
时间t0=时间(0);
while(pthread\u mutex\u trylock(p)){
如果(时间(0)>t0+5)返回0;
}
pthread_mutex_unlock(p);
返回0;
}
void*start3(void*p)
{
sem_wait(&sem);
结构timespects;
时钟获取时间(时钟实时,&ts);
ts.tv_sec+=5;
INTR;
if(r=pthread\u mutex\u timedlock(p和ts)){
printf(“失败:%d%s\n”,r,strerror(r));
}否则{
pthread_mutex_unlock(p);
}
返回0;
}
int main(int argc,字符**argv)
{
int policy=argc>1?调度空闲:调度FIFO;
int a=计划获取优先级最小值(策略);
pthread_attr_t attr;
pthread_t t1、t2、t3;
结构sched_param param={0};
cpu_set_t set={0};
CPU_零(&set);
CPU_集(0,&集);
pthread_setaffinity_np(pthread_self(),sizeof set,&set);
pthread_attr_init(&attr);
pthread_attr_setinheritsched(&attr,pthread_EXPLICIT_SCHED);
pthread_attr_setschedpolicy(&attr,policy);
pthread_mutexttr_ma;
pthread_mutexattr_init(&ma);
pthread_mutexttr_setprotocol(&ma,pthread_PRIO_INHERIT);
pthread_mutextatr_settype(&ma,pthread_MUTEX_ERRORCHECK);
pthread_mutex_t mtx;
pthread_mutex_init(&mtx,&ma);
sem_init(&sem,0,0);
参数sched_优先级=a+1;
pthread_attr_setschedparam(&attr,¶m);
if(pthread_create(&t2,policy==SCHED_IDLE?0:&attr,start2,&mtx))返回1;
参数sched_优先级=a+2;
pthread_attr_setschedparam(&attr,¶m);
if(pthread_create(&t3,policy==SCHED_IDLE?0:&attr,start3,&mtx))返回1;
参数sched_优先级=a;
pthread_attr_setschedparam(&attr,¶m);
if(pthread_create(&t1,&attr,start1,&mtx))返回1;
pthread_-join(t1,0);
pthread_-join(t2,0);
pthread_-join(t3,0);
返回0;
}
Linux的
SCHED_IDLE
是否只允许在内核运行时运行空闲任务 实际上不是闲置的吗?或者我可能还遗漏了什么


这是正确的
SCHED_IDLE
提供的任务比一个漂亮的19任务少70%的CPU时间。

你能把你的
SCHED_IDLE
/
SCHED_OTHER
PI测试代码包括在内吗?@caf:Done。我把两个版本压缩成一个程序,希望在这个过程中我没有弄糟任何东西。谢谢。这使得它不仅对于我的测试目的毫无意义,而且对于它的预期目的也毫无意义:确保降级的任务不会占用任何正常任务的cpu时间。我相信这样的想法是,如果你想要像“从不”这样的保证,你就使用实时策略。在系统上以
SCHED_RR
的方式运行所有东西?
SCHED_IDLE
应该解决的问题是,您需要一个“低于一切”的优先级,而不必显式地使“一切”实时/高于空闲。我想知道这是否真的可能。。。让
init
在prio 10或其他时间以
SCHED_RR
的形式启动所有程序,并让希望优先级较低的进程降到较低的位置。。。大概降低到较低的级别可以在没有特权的情况下完成?我更想考虑的是,如果你有这样的要求,这往往是因为你有一组已知的任务,你永远不想被打断。对于其他方面来说,在“空闲”任务中,您最多可能会损失340个周期中的1个周期这一事实似乎不是问题。它可能应该被称为
SCHED_NICEST
或其他什么;)