Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.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
C++ Can';t在C+中引起优先级反转+;_C++_Pthreads_Real Time_Mutex_Thread Priority - Fatal编程技术网

C++ Can';t在C+中引起优先级反转+;

C++ Can';t在C+中引起优先级反转+;,c++,pthreads,real-time,mutex,thread-priority,C++,Pthreads,Real Time,Mutex,Thread Priority,我试图在一个小型的C++程序上引发优先级反转进行演示,但我做不到:持有互斥体的低优先级线程没有被抢占并在关键部分继续运行。这就是我正在做的: // let's declare a global mutex pthread_mutex_t my_mutex; ... int main(int argc, char **argv) { ... pthread_t normal_thread; pthread_t prio_thread; pthread_mutexattr_t

我试图在一个小型的C++程序上引发优先级反转进行演示,但我做不到:持有互斥体的低优先级线程没有被抢占并在关键部分继续运行。这就是我正在做的:

// let's declare a global mutex
pthread_mutex_t my_mutex;
  ...

int main(int argc, char **argv) {
  ...
  pthread_t normal_thread;
  pthread_t prio_thread;

  pthread_mutexattr_t attr;
  pthread_mutexattr_init (&attr);
  pthread_mutexattr_setprotocol (&attr, PTHREAD_PRIO_NONE);  // ! None !
  pthread_mutex_init(&my_mutex, &attr);

  // create first normal thread (L):
  pthread_create(&normal_thread, NULL, the_locking_start_routine, NULL);

  // just to help the normal thread enter in the critical section
  sleep(2);

  // now will launch:
  // * (M) several CPU intensive SCHED_FIFO threads with priority < 99
  // * (H) one SCHED_FIFO thread that will try to lock the mutex, with priority < 99

  // build Real Time attributes for the Real Time threads:
  pthread_attr_t my_rt_att;
  pthread_attr_init(&my_rt_att);

  // it was missing in the original post and it was also wrong:
  // even setting the SchedPolicy you have to set "InheritSched"
  pthread_attr_setinheritsched(&my_rt_att, PTHREAD_EXPLICIT_SCHED)

  pthread_attr_setschedpolicy(&my_rt_att, SCHED_FIFO);
  struct sched_param params;

  params.sched_priority = 1;
  pthread_attr_setschedparam(&my_rt_att, &params);

  pthread_create(&prio_thread, &my_rt_att, the_CPU_intensive_start_routine, NULL) 

  params.sched_priority = 99;
  pthread_attr_setschedparam(&my_rt_att, &params);

  // create one RealTime thread like this:
  pthread_create(&prio_thread, &my_rt_att, the_locking_start_routine, NULL)  //coma was missing

  ...
}

void *the_locking_start_routine(void *arg) {
  ...
  pthread_mutex_lock(&my_mutex);
  // This thread is on the critical section
  // ... (skipped)
  pthread_mutex_unlock(&my_mutex);
  ...
}
//让我们声明一个全局互斥体
pthread_mutex_t my_mutex;
...
int main(int argc,字符**argv){
...
pthread\u t普通螺纹;
pthread_t prio_线程;
pthread_mutextatr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setprotocol(&attr,pthread_PRIO_NONE);//!NONE!
pthread_mutex_init(&my_mutex,&attr);
//创建第一个普通线程(L):
pthread_create(&normal_thread,NULL,锁定_start_例程,NULL);
//只是为了帮助普通螺纹进入临界段
睡眠(2);
//现在将推出:
//*(M)多个CPU密集型SCHED_FIFO线程,优先级<99
//*(H)一个SCHED_FIFO线程将尝试锁定互斥锁,优先级<99
//为实时线程生成实时属性:
pthread_attr_t my_rt_att;
pthread_attr_init(&my_rt_att);
//它在最初的帖子中丢失了,而且也是错误的:
//即使设置SchedPolicy,也必须设置“InheritSched”
pthread\u attr\u setinheritsched(&my\u rt\u att,pthread\u EXPLICIT\u SCHED)
pthread_attr_setschedpolicy(&my_rt_att,SCHED_FIFO);
结构sched_param params;
params.sched_优先级=1;
pthread_attr_setschedparam(&my_rt_att,¶ms);
pthread\u create(&prio\u thread,&my\u rt\u att,CPU密集型启动例程,NULL)
params.sched_优先级=99;
pthread_attr_setschedparam(&my_rt_att,¶ms);
//创建一个实时线程,如下所示:
pthread\u create(&prio\u thread,&my\u rt\u att,\u locking\u start\u例程,NULL)//coma丢失
...
}
void*锁定启动例程(void*arg){
...
pthread_mutex_lock(&my_mutex);
//此线程位于关键部分
//…(跳过)
pthread_mutex_unlock(&my_mutex);
...
}
。。。但它不起作用,我不能得到我想要的优先级反转

情况就是这样:

据我所知,对于像Linux的CFS这样的调度程序,非实时线程(SCHED_OTHER)将不会运行,直到没有任何实时线程(SCHED_FIFO或SCHED_RR)处于运行状态。但我已经实现了同步运行的线程:

  • (五十) 一个非实时(SCHED_OTHER)线程锁定互斥锁并 消耗CPU
  • (M) 多个实时线程(SCHED_FIFO,&优先级>0)CPU 密集且不等待锁定互斥锁
  • (H) 一个实时线程(SCHED_FIFO和最高优先级)正在等待 锁
有更多的实时CPU密集型线程(M)比我的系统的CPU数量运行。。。但持有锁的非实时线程(L)仍在消耗CPU,并在“M”线程消耗CPU之前完成其工作并释放互斥锁

为什么低优先级线程没有被抢占,应用程序死锁,我无法获得优先级反转?

我在Ubuntu桌面11.04上使用G+4.5.2,内核2.633-13.< /P>< P> RE:我试图在一个小型C++程序中引发优先级反转,以演示目的,但我不能:持有互斥的低优先级线程不被抢占并继续运行…

这是优先级反转场景的开始。低优先级线程获取一个独占资源(例如互斥),高优先级线程在该资源上阻塞

例如,为了正确显示优先级反转的结果,您需要三个线程:低(L)、中(M)和高(H)优先级线程

L锁定一个互斥锁,H为其竞争。所以我在跑,H不是。这已经很糟糕了:重要的线程H正在等待不那么重要的线程L做一些事情

现在M变得可运行并且是计算密集型的。M不关心互斥体;它与H或L无关。但M的优先级比L高,并将L从CPU中踢出

所以现在M继续执行,阻止L运行。这会阻止L到达它释放互斥锁的代码行,也会阻止H获取互斥锁

因此,一个中等优先级的线程M正在运行,而不是最高优先级的线程H

通过阻塞L,M也能够阻塞H:反转


看看你是否能像这样编码。

大多数现代调度程序都有防死锁保护措施,可以在检测到或认为合适的情况下更改一两个时间片的优先级,以防止优先级反转导致死锁。linux是否与您正在使用的任何调度器兼容,我不确定。然而,如果你还没有意识到这一点,那么一定要意识到这一点

  • 您是否以root用户身份运行该程序

  • 这些sysctl参数的值是多少?这是我从Ubuntu盒子里拿的。默认情况下,在1秒的切片中,实时时间仅为0.95秒:

    kernel.sched_rt_period_us = 1000000
    kernel.sched_rt_runtime_us = 950000
    
    这可以防止实时域占用所有CPU。如果你想要实时,你必须禁用这些参数

  • 见:


    如果将
    sched\u rt\u runtime\u us设置为-1,则禁用此安全机制。

    请显示启动例行程序的所有代码。我看不出它在锁和开锁之间做什么。也在临界区之外-大概在某个地方有一个循环,你已经变成了点?如果它在CS内部,为什么它会被抢占呢?它是唯一一个线程就绪/正在运行,因为所有其他线程都卡在互斥锁上。请移到下面回答(无论是不是)大多数现代调度程序都有防死锁保护措施,可以在一两个时间段内更改优先级,以防止优先级反转导致死锁,当检测到或认为适当时。linux是否与您正在使用的任何调度器兼容,我不确定。然而,如果你不是alrea,一定要意识到这一点