42

Linux オペレーティング システムの c/c++ でプロセスの CPU アフィニティを設定するプログラムによる方法はありますか?

4

6 に答える 6

54

を使用する必要がありますsched_setaffinity(2)

たとえば、CPU 0 と 2 のみで実行するには、次のようにします。

#define _GNU_SOURCE
#include <sched.h>

cpu_set_t  mask;
CPU_ZERO(&mask);
CPU_SET(0, &mask);
CPU_SET(2, &mask);
int result = sched_setaffinity(0, sizeof(mask), &mask);

(0最初のパラメーターは現在のプロセスを意味し、制御したい他のプロセスの場合は PID を指定します)。

も参照してくださいsched_getcpu(3)

于 2008-11-11T13:52:48.417 に答える
10

プロセス レベルで sched_setaffinity を使用するか、個々のスレッドに対してpthread_attr_setaffinity_npを使用します。

于 2008-11-11T13:57:05.867 に答える
4

sched_setaffinity+sched_getaffinity最小限の C 実行可能な例

この例は、私の回答から抜粋したものです: How to use sched_getaffinity and sched_setaffinity in Linux from C? 質問はこれのサブセットであるため、質問は重複していないと思います.C ++についてのみ質問sched_getaffinityし、言及していません。

この例では、アフィニティを取得して変更し、 で有効になっているかどうかを確認しsched_getcpu()ます。

main.c

#define _GNU_SOURCE
#include <assert.h>
#include <sched.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void print_affinity() {
    cpu_set_t mask;
    long nproc, i;

    if (sched_getaffinity(0, sizeof(cpu_set_t), &mask) == -1) {
        perror("sched_getaffinity");
        assert(false);
    }
    nproc = sysconf(_SC_NPROCESSORS_ONLN);
    printf("sched_getaffinity = ");
    for (i = 0; i < nproc; i++) {
        printf("%d ", CPU_ISSET(i, &mask));
    }
    printf("\n");
}

int main(void) {
    cpu_set_t mask;

    print_affinity();
    printf("sched_getcpu = %d\n", sched_getcpu());
    CPU_ZERO(&mask);
    CPU_SET(0, &mask);
    if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) == -1) {
        perror("sched_setaffinity");
        assert(false);
    }
    print_affinity();
    /* TODO is it guaranteed to have taken effect already? Always worked on my tests. */
    printf("sched_getcpu = %d\n", sched_getcpu());
    return EXIT_SUCCESS;
}

GitHub アップストリーム.

コンパイルして実行します。

gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
./main.out

出力例:

sched_getaffinity = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
sched_getcpu = 9
sched_getaffinity = 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
sched_getcpu = 0

つまり、次のことを意味します。

  • 最初は、16 個のコアすべてが有効になっていて、プロセスはコア 9 (10 番目のコア) でランダムに実行されていました。
  • アフィニティを最初のコアのみに設定した後、プロセスは必然的にコア 0 (最初のコア) に移動されました。

このプログラムを次のように実行するのも楽しいですtaskset:

taskset -c 1,3 ./a.out

次の形式の出力が得られます。

sched_getaffinity = 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 
sched_getcpu = 2
sched_getaffinity = 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
sched_getcpu = 0

したがって、最初から親和性が制限されていることがわかります。

これは、アフィニティが子プロセスによって継承されるため機能します。これtasksetはフォークです: フォークされた子プロセスによる CPU アフィニティの継承を防ぐにはどうすればよいですか?

パイソン:os.sched_getaffinityos.sched_setaffinity

参照: Python を使用して CPU の数を調べる方法

Ubuntu 16.04 でテスト済み。

于 2019-02-01T11:09:31.433 に答える
2

要するに

unsigned long mask = 7; /* processors 0, 1, and 2 */
unsigned int len = sizeof(mask);
if (sched_setaffinity(0, len, &mask) < 0) {
    perror("sched_setaffinity");
}

詳細については、CPU アフィニティを参照してください

于 2008-11-11T14:20:56.817 に答える