【问题标题】:pthread_attr_setschedparam() returns invalid argument … (Linux, C, Ubuntu 18.04.4)pthread_attr_setschedparam() 返回无效参数……(Linux、C、Ubuntu 18.04.4)
【发布时间】:2021-05-06 05:20:38
【问题描述】:

大家好!

我无法在代码中超越这一点。 我怀疑这是资源限制方面的操作系统问题?

我看到消息来源说 RTPRIO 0 最低,99 最高。 ... 和其他人说相反的话。

我似乎找不到关于内核在进程中获得近实时线程的良好参考。

我曾希望有一个 4 核处理器,其中一个核心专用于下面代码中的串行线程。 此外,当这个串行线程进行系统调用时......专用内核会将任务切换到这个系统调用。

我们将不胜感激任何建议和帮助。

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/resource.h>



//-----------------------------------
// signal Handler stuff.
//-----------------------------------
static
struct  sigaction mySigActTerm;

volatile
int     myTerminate = 0;

void terminateHandler(int signum, siginfo_t *info, void *ptr)
{
  // set a flag here and get out.
  myTerminate = 1;
}



void getNowTime(char* str)
{
  time_t    rawtime;
  time(&rawtime);
  ctime_r(&rawtime, str);

  // clobber the unwanted newline.
  str[24] = '\0';
}



void myResLimit()
{
  struct
  rlimit    procLimit;

  char      strNowTime[26];

  getrlimit(RLIMIT_RTTIME, &procLimit);
  getNowTime(strNowTime);
  fprintf(stderr, "%s - RLIMIT_RTTIME: soft=%lld, hard=%lld\n", strNowTime, (long long) procLimit.rlim_cur, (long long)procLimit.rlim_max);

  getrlimit(RLIMIT_RTPRIO, &procLimit);
  getNowTime(strNowTime);
  fprintf(stderr, "%s - RLIMIT_RTPRIO: soft=%lld, hard=%lld\n", strNowTime, (long long) procLimit.rlim_cur, (long long) procLimit.rlim_max);

  getrlimit(RLIMIT_CPU, &procLimit);
  getNowTime(strNowTime);
  fprintf(stderr, "%s - RLIMIT_CPU: soft=%lld, hard=%lld\n", strNowTime, (long long) procLimit.rlim_cur, (long long) procLimit.rlim_max);
}



void*   serialThread(void* arg)
{
    while (1) {
        
    }
}



//-----------------------------------
// the one and only MAIN.
//-----------------------------------
int main()
{
  //-----------------------------------------------
  // locals.
  int               rtn;

  char              strNowTime[26];

  pthread_t         serialThdID;

  pthread_attr_t    serialAttr;

  struct
  sched_param       serialParam;


  //-----------------------------------------------
  // Log OS resource limits.
  myResLimit();

  //-----------------------------------------------
  // initialize the signals struct.
  // ... and setup signals.
  memset(&mySigActTerm, 0, sizeof(mySigActTerm));
  mySigActTerm.sa_sigaction = terminateHandler;
  mySigActTerm.sa_flags = SA_SIGINFO;

  sigaction(SIGTERM, &mySigActTerm, NULL);


  //-----------------------------------------------
  // set initial default pthread attr values.
  if ((rtn = pthread_attr_init(&serialAttr)) != 0) {
    getNowTime(strNowTime);
    fprintf(stderr, "%s - main() - pthread_attr_init()\n%s\n", strNowTime, strerror(rtn));
    exit(EXIT_FAILURE);
  }

  //-----------------------------------------------
  // set for best near real time policy.
  if ((rtn = pthread_attr_setschedpolicy(&serialAttr, SCHED_FIFO)) !=0) {
    getNowTime(strNowTime);
    fprintf(stderr, "%s - main() - pthread_attr_setschedpolicy()\n%s\n", strNowTime, strerror(rtn));
    exit(EXIT_FAILURE);
  }

  //-----------------------------------------------
  // set to explicit inherit or attr obj will be ignored.
  if ((rtn = pthread_attr_setinheritsched(&serialAttr, PTHREAD_EXPLICIT_SCHED)) !=0) {
    getNowTime(strNowTime);
    fprintf(stderr, "%s - main() - pthread_attr_setinheritsched()\n%s\n", strNowTime, strerror(rtn));
    exit(EXIT_FAILURE);
  }

  //-----------------------------------------------
  // set to un-limited thread priority.
  serialParam.sched_priority = 0;
  if ((rtn = pthread_attr_setschedparam(&serialAttr, &serialParam)) !=0) {
    getNowTime(strNowTime);
    fprintf(stderr, "%s - main() - pthread_attr_setschedparam()\n%s\n", strNowTime, strerror(rtn));
    exit(EXIT_FAILURE);
  }

  //-----------------------------------------------
  // start the new thread.
  if ((rtn = pthread_create(&serialThdID, &serialAttr, serialThread, NULL)) == 0) {
    getNowTime(strNowTime);
    fprintf(stderr, "%s - starting serial thread.\n", strNowTime);
  }
  else {
    getNowTime(strNowTime);
    fprintf(stderr, "%s - main() - pthread_create() returned %d\n%s\n", strNowTime, rtn, strerror(rtn));
    exit(EXIT_FAILURE);
  }

  //-----------------------------------------------
  // no need to keep this junk if pthread_create() succeeded.
  if ((rtn = pthread_attr_destroy(&serialAttr)) != 0) {
    getNowTime(strNowTime);
    fprintf(stderr, "%s - main() - pthread_attr_destroy()\n%s\n", strNowTime, strerror(rtn));
  }




  while (myTerminate == 0) {

  }
}

输出是:

  • 日期时间 - RLIMIT_RTTIME:软=-1,硬=-1
  • dateTime - RLIMIT_RTPRIO: soft=-1, hard=-1
  • dateTime - RLIMIT_CPU: soft=-1, hard=-1
  • dateTime - main() - pthread_attr_setschedParam()
  • 参数无效

【问题讨论】:

  • 不确定pthreads 版本,但是对于RT 调度程序[sched_setscheduler],优先级值越高越好[nice 的反面]。
  • 但是,IIRC,提升优先级 [通过 sched_setschedulersched_paramsched_priority] 是一项特权操作 [要么是 root 要么拥有 CAP_SYS_NICE]
  • sudo setcap cap_sys_resource+ep /path/exec ... 是我见过并尝试过的。

标签: c linux pthreads real-time ubuntu-18.04


【解决方案1】:

您正在尝试将调度优先级 0 与无效的 SCHED_FIFO 调度策略一起使用。

您正在使用pthread_attr_setschedpolicy 将调度策略设置为SCHED_FIFO。该函数的手册页指出:

策略支持的值为 SCHED_FIFO、SCHED_RR 和 SCHED_OTHER,语义在 sched_setscheduler(2) 中描述。

sched_setscheduler 的手册页进一步说明了 SCHED_FIFO 的以下内容:

SCHED_FIFO 只能用于高于 0 的静态优先级,这意味着当 SCHED_FIFO 进程变为可运行时,它将始终 立即抢占任何当前正在运行的 SCHED_OTHER、SCHED_BATCH 或 SCHED_IDLE 进程。 SCHED_FIFO 是一种简单的调度算法,没有 时间切片。

因此对 serialParam.sched_priority 使用大于 0 的值会起作用。

【讨论】:

  • 然后我被告知错了...感谢您清除此问题。我能够运行代码,但我仍然没有得到实时。我在一个 select() 附近被抢占,它设置为超时 3 毫秒,但 select() 中的总时间是 4.4 毫秒。我不知道下一步该做什么。感谢您的帮助!
猜你喜欢
  • 2021-05-06
  • 1970-01-01
  • 2011-05-20
  • 2012-09-28
  • 2020-06-09
  • 2021-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多