Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.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++ pthread FIFO调度不是严格确定的吗?_C++_Multithreading_Gdb_Pthreads_Rhel - Fatal编程技术网

C++ pthread FIFO调度不是严格确定的吗?

C++ pthread FIFO调度不是严格确定的吗?,c++,multithreading,gdb,pthreads,rhel,C++,Multithreading,Gdb,Pthreads,Rhel,我试图使该线程在其所在的进程运行时始终在一个CPU内核上运行(共24个): void *t_mon_func(void *) { while (true) { if (f) { break_on(); } } return nullptr; } 我将其配置为SCHED_FIFO调度和最大优先级。我有50个其他线程使用此线程函数运行(默认优先级): void *tfunc(void *) { std::atomic<unsigned> i

我试图使该线程在其所在的进程运行时始终在一个CPU内核上运行(共24个):

void *t_mon_func(void *)
{
  while (true) {
    if (f) {
      break_on();
    }
  }
  return nullptr;
}
我将其配置为SCHED_FIFO调度和最大优先级。我有50个其他线程使用此线程函数运行(默认优先级):

void *tfunc(void *)
{
  std::atomic<unsigned> i = 0;
  while (true) {
    if (f) {
      ++i;
    }
  }
  return nullptr;
}
void*tfunc(void*)
{
std::原子i=0;
while(true){
如果(f){
++一,;
}
}
返回空ptr;
}
在gdb中,我在
break_on
函数上设置了一个断点,继续该程序,然后触发该程序将
f
(全局变量)的值更改为非零值(通过来自低优先级线程的系统调用)。当断点被命中时,许多低优先级线程中的
i
的值为数千或上万。这似乎表明实时、高优先级线程并不总是在运行(进程正在运行)。还是我遗漏了什么?完整的程序在x.cc中,此处:。(我以root用户身份运行该程序。)

这似乎表明实时、高优先级的线程并不总是在运行

你的结论不是根据观察到的事实得出的

在Linix上,当在
SCHED_FIFO
线程中遇到断点时,该线程不再可运行,但所有其他线程都可运行,因此继续运行。(注意:当任何线程到达断点时,其他操作系统会停止所有线程,但Linux不会。)

由于正在调试FIFO线程,内核(最终)通知GDB(通过
waitpid
return)该线程已停止(其他线程继续运行)

当GDB注意到FIFO线程已停止时,它会停止所有其他线程(仅在
all stop
模式下),并最终返回提示。只有在这一时刻,您才能检查所有线程中
i
的值

虽然GDB唤醒和停止所有线程之间的时间非常短(通常为毫秒),但其他线程设法将变量10增加到数千次也就不足为奇了


是的,pthread FIFO调度似乎是确定的。我在问这个问题时做了两个假设,其中一个或两个都是错误的:

  • x86_64体系结构允许设置一个执行断点,使一个内核跳转到ISR,而所有其他内核暂停执行
  • 用于x86_64的GDB将这种功能用于执行断点
  • 我将低优先级线程的函数更改为:

    void *tfunc(void *)
    {
      std::atomic<unsigned> i = 0;
    
      while (!flag) {
        ;
      }
      while (run) {
        ++i;
      }
    
      if (i) {
        std::cout << i << std::endl;
      }
    
      return nullptr;
    }
    
    (修订后的计划在x.cc中。)

    在任何低优先级线程中,
    i
    的最大输出值为13

    有一点我仍然不明白,如果我将低优先级线程的数量增加到10个以上,程序将永远不会退出


    (我试图删除该问题,但得到的答复是,最好不要删除有答案的问题。)

    high priorty!=实时!=始终运行裸机断言!=有用我不认为你的测试测试你认为它测试的东西,因为它是基于启动和停止东西,而不是在稳态条件下运行的东西。平台很可能会以某种特定的顺序启动和停止某些东西,从而使某些东西在进程的各个点上运行,而其他东西在进程的各个点上不运行。@Walk我认为问题在于您自己的语句<代码>“…实时、高优先级的线程不知何故并不总是在运行…”似乎等同于高优先级和实时性的概念。操作系统内核交换线程的原因有很多。您似乎假设将原子int
    f
    设置为no零值将作为在高优先级线程中交换的信号——事实并非如此。是的,我希望有人知道比“任何数量的原因”更具体的情况。在具有确定性调度的实时操作系统中,一个比任何其他线程都具有更高优先级的可运行线程总是在运行,除非我认为所有内核上都运行ISR。我不明白为什么我的程序中的高优先级线程永远无法运行,它不进行系统调用。嗯,但是当我向gdb脚本添加
    show non-stop
    时,输出是
    在不停止模式下控制次线程是关闭的。
    @WaltK
    不停止模式是关闭的
    相当于
    所有停止模式
    。没什么新鲜事吗?在非停止模式下,其他线程将继续运行,增加的
    i
    甚至更多。那么x86体系结构是否缺乏配置执行断点的能力,该断点将停止所有内核,只允许单个内核执行相关的ISR?@WaltK我不知道,但您正在混合完全不相关的东西。在用户空间(程序运行的地方)附近没有
    ISR
    s。我认为断点会导致切换到内核上下文,至少对于碰到断点的内核(以及进入ISR)。
    void *t_mon_func(void *)
    {
      while (!flag) {
        ;
      }
      run = 0;
      flag = 0;
    
      return nullptr;
    }