这些教程通常需要一个终端用于执行教程应用程序,至少一个额外的终端用于执行各种影响应用程序行为的压力测试,或用于监控以捕获其操作的统计信息。最好通过 SSH 远程访问执行教程的系统,以避免桌面 GUI 中断影响测量结果(非xkernel内核)。
教程包括:
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
int main() {
    pthread_t thread = pthread_self(); // 获取当前线程
    cpu_set_t cpµset;                  // 定义 CPU 集合
    int cpu = 2;                       // 要绑定的 CPU 核心
    CPU_ZERO(&cpµset);    // 清除 CPU 集合
    CPU_SET(cpu, &cpµset); // 将 CPU 2 添加到集合中
    // 设置线程的 CPU 亲和性
    if (pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpµset) != 0) {
        perror("设置 CPU 亲和性失败");
        return 1;
    }
    printf("线程已成功绑定到 CPU %d。\n", cpu);
    return 0;
}
        # 可以启动一个程序并将其绑定到特定的 CPU(比如 CPU 0 和 CPU 1)
sudo taskset -c 0,1 my_program
        开始在CPU2上执行应用程序(非隔离)
latency -c2 -t0 -p 100 -P 99 -h
        平均值为 30µs
开始在CPU1上执行应用程序(隔离)
latency -c1 -t0 -p 100 -P 99 -h
        平均值为 10µs
页面错误(Page faults)会对确定性产生负面影响。内存锁定可以防止应用程序中大部分甚至全部页面错误的发生。
  #include <stdio.h>
  #include <stdlib.h>
  #include <sys/mman.h>  // 包含 mlockall 函数的头文件
  #include <unistd.h>    // 包含 sleep 函数的头文件
  int main() {
      // 使用 mlockall 锁定进程的所有内存到物理内存中
      // MCL_CURRENT: 锁定当前内存页
      // MCL_FUTURE: 锁定未来分配的内存页
      if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
          perror("内存锁定失败");
          return 1;
      }
      printf("内存已锁定,防止交换到磁盘。\n");
      // 模拟程序运行,期间内存保持锁定
      for (int i = 0; i < 10; i++) {
          printf("程序运行中...\n");
          sleep(1);  // 休眠 1 秒
      }
      // 解除内存锁定
      if (munlockall() != 0) {
          perror("解除内存锁定失败");
          return 1;
      }
      printf("内存锁定已解除。\n");
      return 0;
  }
        可以通过健康监测工具健康进程的Page faults次数
sudo sjournal_run 1h
        
实时应用程序会抢占其他非实时的应用程序。优先级参数设置执行工作负载的线程优先级。当此参数被省略或设置为零时,线程不是实时的。将其设置为99可确保RT执行。
使用代码设置为实时线程优先级
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sched.h>
#include <unistd.h>
// 线程函数
void* thread_func(void* arg) {
    while (1) {
        // 模拟一些工作
        sleep(1);
    }
    return NULL;
}
int main() {
    pthread_t thread;
    struct sched_param param;
    int policy = SCHED_FIFO;  // 使用 FIFO 实时调度策略
    int max_priority, min_priority;
    // 创建线程
    if (pthread_create(&thread, NULL, thread_func, NULL) != 0) {
        perror("无法创建线程");
        return 1;
    }
    // 获取 SCHED_FIFO 策略的最大和最小优先级
    max_priority = sched_get_priority_max(SCHED_FIFO);
    min_priority = sched_get_priority_min(SCHED_FIFO);
    printf("SCHED_FIFO 最大优先级: %d, 最小优先级: %d\n", max_priority, min_priority);
    // 设置线程的优先级(选择一个合适的值,如最大优先级)
    param.sched_priority = max_priority;
    // 设置线程的调度策略和优先级
    if (pthread_setschedparam(thread, policy, ¶m) != 0) {
        perror("无法设置线程优先级");
        return 1;
    }
    printf("线程已设置为实时优先级 (SCHED_FIFO, 优先级: %d)\n", param.sched_priority);
    // 等待线程结束
    pthread_join(thread, NULL);
    return 0;
}
        使用命令行设置线程为实时线程
# 将正在运行的进程转换为实时调度策略
sudo chrt -f 99 <priority> <pid>
# 以实时调度策略启动新进程
sudo chrt -f 99 <priority> <command>
        使用下面的命令查看设置是否成功
chrt -p <pid>