Linux オペレーティング システムの c/c++ でプロセスの CPU アフィニティを設定するプログラムによる方法はありますか?
6 に答える
を使用する必要があります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)
。
プロセス レベルで sched_setaffinity を使用するか、個々のスレッドに対してpthread_attr_setaffinity_npを使用します。
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;
}
コンパイルして実行します。
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_getaffinity
とos.sched_setaffinity
Ubuntu 16.04 でテスト済み。
要するに
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 アフィニティを参照してください