C에서 sched_setaffinity 함수 사용

Jinku Hu 2023년10월12일
  1. sched_setaffinity함수를 사용하여 프로세스 실행을 특정 CPU로 제한
  2. CPU_SET매크로를 사용하여 프로세스를 바인딩 할 CPU 코어를 지정합니다
C에서 sched_setaffinity 함수 사용

이 기사에서는 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 <sys/wait.h>
#include <unistd.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를 사용하여 자식을 기다립니다. 시연 된 동작을 관찰하려면 Linux 시스템에서 널리 사용되는htop 명령 줄 유틸리티를 사용하여 시스템 프로세스를 관찰 할 수 있습니다.

#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.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);
  }
}
작가: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

관련 문장 - C Process