我正在寫一個使用一定比例的CPU的小程序。基本策略是,我將持續檢查CPU使用情況,並在使用級別高於給定值時使進程處於睡眠狀態。另外,由於我使用的是MacOS(沒有像Linux一樣的proc/stat,C#中沒有PerformanceCounter),所以我必須在另一個線程中執行top
命令並從中獲得CPU使用率。多線程C程序中的共享字段是否使用CPU很多?
問題是我一直在獲得CPU的非常高的使用率,即使我給出一個小的值作爲參數。經過多次實驗,似乎是由多線程共享字段造成的。
這裏是我的代碼(代碼1)和實驗:
(代碼2)起初,我還以爲它是shell命令使使用率非常高,所以我在run()
評論的無限循環,只留下getCpuUsage()
運行。但是,CPU使用率幾乎爲零。
(代碼3)然後,我編寫了另一個run()
獨立於cpuUsage的函數,該函數旨在使用50%的CPU。它運作良好!我認爲代碼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);
}
}
sleep不會停止線程的CPU使用率。 –
@MarrowGnower,但是我的代碼的第三個版本效果很好,這表明'usleep()'確實會停止CPU使用。 – POPOL
順便說一句,POSIX不允許通過多個控制線程同時讀取和寫入存儲器位置 - 「應用程序應確保受到多於一個控制線程(線程或進程)對任何存儲器位置的訪問受到限制,使得沒有線程的控制可以讀取或修改內存位置,而另一個控制線程可能正在修改它。「 – chill