pthread FIFO调度是否严格确定性?

问题描述 投票:-1回答:2

[我正在尝试使该线程始终在一个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;
}

[在gdb中,我在break_on函数上设置了一个断点,继续执行程序,然后触发该程序,以将f(全局变量)的值更改为非零值(通过从优先级较低的线程)。当达到断点时,许多低优先级线程中的i的值在成千上万。这似乎表明实时,高优先级线程并非总是在运行(在进程运行时)。还是我错过了什么?完整的程序在x.cc中https://github.com/ywkaras/MiscRepo/tree/master/TWATCH。 (我以超级用户身份运行该程序。)

c++ multithreading gdb pthreads rhel
2个回答
1
投票

这似乎表明实时的高优先级线程总不能以某种方式运行

您的结论并非来自观察到的事实。

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

自调试FIFO线程以来,内核(最终)(通过waitpid返回)通知GDB该线程已停止(其他线程继续运行)。

[当GDB注意到FIFO线程已停止时,它随后停止所有其他线程(仅在all-stop模式下),最后返回提示。只有到那时,您才能检查所有线程中的i的值。

虽然GDB唤醒和停止所有线程之间的时间很短(通常为毫秒),但其他线程设法将变量增加十万倍的时间也就不足为奇了。



0
投票

看来,是的,pthread FIFO调度是确定性的。我在问这个问题时有两个假设,一个或两个都是错误的:

  1. x86_64体系结构允许设置执行断点,该断点将导致一个内核跳转到ISR,而所有其他内核则暂停执行。
  2. 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;
}

以及高优先级线程的功能:

void *t_mon_func(void *)
{
  while (!flag) {
    ;
  }
  run = 0;
  flag = 0;

  return nullptr;
}

(修订后的程序在https://github.com/ywkaras/MiscRepo/tree/master/TWATCH2中的x​​.cc中。)>

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

我仍然不了解的一件事是,如果我将低优先级线程的数量增加到超过10个,该程序将永远不会退出。

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

© www.soinside.com 2019 - 2024. All rights reserved.