一定の割合のCPUを使用する小さなプログラムを書いています。基本的な戦略は、CPU使用率を継続的にチェックし、使用率のレベルが指定された値よりも高い場合はプロセスをスリープ状態にすることです。
さらに、私はMacOS(Linuxのようなproc / statなし、C#のPerformanceCounterなし)をtop
使用しているため、別のスレッドでコマンドを実行し、そこからCPU使用率を取得する必要があります。
問題は、引数として小さな値を指定しても、CPUの使用率が非常に高くなることです。そして、いくつかの実験の後、それはマルチスレッドによる共有フィールドによって引き起こされたようです。
これが私のコード(コード1)と実験です:
(コード2)当初、シェルコマンドを使用すると使用率が非常に高くなると思ったので、の無限ループについてコメントしrun()
、実行中のみを残しましたgetCpuUsage()
。ただし、CPU使用率はほぼゼロです。
(コード3)次に、run()
CPUの50%を使用することを目的としたcpuUsageから独立した別の関数を作成しました。それはうまくいきます!コード1とコード3の唯一の違いは、の使用法だと思いますcpuUsage
。だから私はスレッド間でフィールドを共有することがCPUをたくさん使うのだろうかと思っていますか?
コード1
const char CPU_COMMAND[] = "top -stats cpu -l 1 -n 0| grep CPU\\ usage | cut -c 12-15";
int cpuUsage; // shared field that stores the cpu usage
// thread that continuously check CPU usage
// and store it in cpuUsage
void getCpuUsage() {
char usage[3];
FILE *out;
while (1) {
out = popen(CPU_COMMAND, "r");
if (fgets(usage, 3, out) != NULL) {
cpuUsage = atof(usage);
} else {
cpuUsage = 0;
}
pclose(out);
}
}
// keep the CPU usage under ratio
void run(int ratio) {
pthread_t id;
int ret = pthread_create(&id, NULL, (void *)getCpuUsage, NULL);
if (ret!=0) printf("thread error!");
while (1) {
// if current cpu usage is higher than ration, make it asleep
if (cpuUsage > ratio) {
usleep(10);
}
}
pthread_join(id, NULL);
}
コード2
// keep the CPU usage under ratio
void run(int ratio) {
pthread_t id;
int ret = pthread_create(&id, NULL, (void *)getCpuUsage, NULL);
if (ret!=0) printf("thread error!");
/*while (1) {
// if current cpu usage is higher than ration, make it asleep
if (cpuUsage > ratio) {
usleep(10);
}
}*/
pthread_join(id, NULL);
}
コード3
void run() {
const clock_t busyTime = 10;
const clock_t idleTime = busyTime;
while (1) {
clock_t startTime = clock();
while (clock() - startTime <= busyTime);
usleep(idleTime);
}
}