迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > C语言 >

在 C 语言中使用 sched_setaffinity 函数

作者:迹忆客 最近更新:2023/03/28 浏览次数:

本文将介绍几种如何在 C 语言中使用 sched_setaffinity 函数的方法。


使用 sched_setaffinity 函数将进程执行限制在特定的 CPU 上

如今,多核硬件无处不在,操作系统需要管理在这些核上同时运行的多个进程。操作系统中负责管理进程/线程执行的部分称为调度程序。调度程序尝试在可用内核之间有效地分配所有现有进程/线程,并相应地分配时间片。调度是操作系统中最困难的设计问题之一,因为它是给定系统的主要性能保证。没有与调度程序交互的标准 C 接口,但是某些 OS 提供了系统调用来修改多个流程调度参数。

sched_setaffinity 是 GNU C 库的一部分,它主要基于特定于 Linux 的功能。该函数设置所谓的 CPU 亲和力掩码,它表示可以在其上执行进程的 CPU 内核集。sched_setaffinity 将 PID 值作为第一个参数,并将 sizeof(cpu_set_t) 作为第二个参数。第三个参数是 cpu_set_t 类型,它是一个不透明的结构,需要使用 <sched.h> 头文件中的预定义宏进行操作。但是请注意,应定义 _GNU_SOURCE 宏以使这些功能和宏可用。在下面的示例中,我们实现了一个程序,该程序将来自用户的三个整数用作命令行参数,并将其存储以分别表示父/子进程 CPU 编号和几次循环迭代。然后,使用 CPU_ZERO 宏清除 cpu_set_t 变量,并调用 fork 产生一个子进程。

#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
                               } while (0)

int main(int argc, char *argv[]) {
    cpu_set_t set;
    int parentCPU, childCPU, wstatus;
    long nloops;

    if (argc != 4) {
        fprintf(stderr, "Usage: %s parent-cpu child-cpu num-loops\n",
                argv[0]);
        exit(EXIT_FAILURE);
    }

    parentCPU = strtol(argv[1], NULL, 0);
    childCPU = strtol(argv[2], NULL, 0);
    nloops = strtol(argv[3], NULL, 0);

    CPU_ZERO(&set);

    switch (fork()) {
        case -1:
            errExit("fork");

        case 0:
            CPU_SET(childCPU, &set);

            if (sched_setaffinity(getpid(), sizeof(set), &set) == -1)
                errExit("sched_setaffinity");

            for (int j = 0; j < nloops; j++)
                getpid();

            exit(EXIT_SUCCESS);

        default:
            CPU_SET(parentCPU, &set);

            if (sched_setaffinity(getpid(), sizeof(set), &set) == -1)
                errExit("sched_setaffinity");

            for (int j = 0; j < nloops; j++)
                getpid();

            wait(NULL);
            exit(EXIT_SUCCESS);
    }
}

使用 CPU_SET 宏指示 CPU 内核将进程绑定到

sched_setaffinity 函数是每个进程或线程调用的;因此,一旦 fork 返回,我们就可以为父进程和子进程指定不同的 CPU 掩码。CPU_SET 宏用于修改先前归零的 cpu_set_t 结构体,然后将其传递给 sched_setaffinity 调用。请注意,每个进程执行一个循环,在其中它们调用 getpid 来占用 CPU 资源并简化示例的演示。父进程在上一个示例中使用 wait 调用来等待子级,在下一个示例中使用 waitpid 来等待子级。如果你想观察所演示的行为,则可以使用 htop 命令行实用程序来观察系统进程,该实用程序在 Linux 系统上广泛使用。

#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
                               } while (0)

int main(int argc, char *argv[]) {
    cpu_set_t set;
    int parentCPU, childCPU, wstatus;
    long nloops;

    if (argc != 4) {
        fprintf(stderr, "Usage: %s parent-cpu child-cpu num-loops\n",
                argv[0]);
        exit(EXIT_FAILURE);
    }

    parentCPU = strtol(argv[1], NULL, 0);
    childCPU = strtol(argv[2], NULL, 0);
    nloops = strtol(argv[3], NULL, 0);

    CPU_ZERO(&set);

    pid_t c_pid = fork();
    if (c_pid == -1)
        errExit("fork");

    switch (c_pid) {
        case -1:
            errExit("fork");

        case 0:
            CPU_SET(childCPU, &set);

            if (sched_setaffinity(getpid(), sizeof(set), &set) == -1)
                errExit("sched_setaffinity");

            for (int j = 0; j < nloops; j++)
                getpid();

            exit(EXIT_SUCCESS);

        default:
            CPU_SET(parentCPU, &set);

            if (sched_setaffinity(getpid(), sizeof(set), &set) == -1)
                errExit("sched_setaffinity");

            for (int j = 0; j < nloops; j++)
                getpid();

            if (waitpid(c_pid, &wstatus, WUNTRACED | WCONTINUED) == -1)
                errExit("waitpid");

            exit(EXIT_SUCCESS);
    }
}

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

在 C 语言中使用 typedef enum

发布时间:2023/05/07 浏览次数:181 分类:C语言

本文介绍了如何在 C 语言中使用 typedef enum。使用 enum 在 C 语言中定义命名整数常量 enum 关键字定义了一种叫做枚举的特殊类型。

C 语言中的静态变量

发布时间:2023/05/07 浏览次数:151 分类:C语言

本文介绍了如何在 C 语言中使用静态变量。在 C 语言中使用 static 变量在函数调用之间保存变量值

C 语言中生成随机数

发布时间:2023/05/07 浏览次数:64 分类:C语言

本文演示了如何在 C 语言中生成随机数。使用 rand 和 srand 函数在 C 语言中生成随机数

C 语言中的 i++ 与++i

发布时间:2023/05/07 浏览次数:83 分类:C语言

本文演示了如何在 C 语言中使用前缀增量与后缀增量运算符。C 语言中++i 和 i++ 记号的主要区别

C 语言中获取当前工作目录

发布时间:2023/05/07 浏览次数:182 分类:C语言

本文演示了如何在 C 语言中获取当前工作目录。使用 getcwd 函数获取当前工作目录的方法

C 语言中的位掩码

发布时间:2023/05/07 浏览次数:126 分类:C语言

本文介绍了如何在 C 语言中使用位掩码。使用 struct 关键字在 C 语言中定义位掩码数据

C 语言中的排序函数

发布时间:2023/05/07 浏览次数:181 分类:C语言

本文演示了如何在 C 语言中使用标准库排序函数。使用 qsort 函数对 C 语言中的整数数组进行排序

C 语言中的 extern 关键字

发布时间:2023/05/07 浏览次数:114 分类:C语言

本文介绍了如何在 C 语言中使用 extern 关键字。C 语言中使用 extern 关键字来声明一个在其他文件中定义的变量

C 语言中的 #ifndef

发布时间:2023/05/07 浏览次数:186 分类:C语言

本文介绍了如何在 C 语言中使用 ifndef。在 C 语言中使用 ifndef 保护头文件不被多次包含 C 语言中的头文件用于定义同名源文件中实现的函数的接口。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便