Linuxオペレーティングシステムのc/c ++でプロセスのCPUアフィニティを設定するプログラムによる方法はありますか?.
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実行可能例
この例は、次の私の回答から抽出されました: CからLinuxでsched_getaffinityとsched_setaffinityを使用する方法 質問はこの質問のサブセットであるため、重複していないと思います。 _sched_getaffinity
_についてのみ尋ね、C++については触れません。
この例では、アフィニティを取得して変更し、 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
_
つまり、次のことを意味します。
このプログラムを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アフィニティの継承を防ぐ方法は?
Ubuntu16.04でテスト済み。
私は何が起こっているのかを理解するために多くの努力をしてきたので、私のような人々を助けるためにこの答えを追加します(私はlinuxmintでgcc
コンパイラを使用します)
#include <sched.h>
cpu_set_t mask;
inline void assignToThisCore(int core_id)
{
CPU_ZERO(&mask);
CPU_SET(core_id, &mask);
sched_setaffinity(0, sizeof(mask), &mask);
}
int main(){
//cal this:
assignToThisCore(2);//assign to core 0,1,2,...
return 0;
}
ただし、このオプションをコンパイラコマンドに追加することを忘れないでください。-D _GNU_SOURCE
オペレーティングシステムが特定のコアにプロセスを割り当てる可能性があるため、GRUB_CMDLINE_LINUX_DEFAULT="quiet splash isolcpus=2,3"
にあるgrubファイルにこの/etc/default
を追加し、ターミナルでSudo update-grub
を実行して、コアを予約できます。欲しいです
要するに
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アフィニティ を参照してください