多线程C程序中的共享字段是否大量使用CPU?

多线程C程序中的共享字段是否大量使用CPU?,c,multithreading,unix,C,Multithreading,Unix,我正在写一个小程序,使用一定比例的CPU。基本策略是,我将持续检查CPU使用情况,如果使用水平高于给定值,则使进程休眠 此外,由于我使用的是MacOS(不像Linux那样没有proc/stat,C#中没有PerformanceCounter),因此我必须在另一个线程中执行top命令,并从中获取CPU使用率 问题是,即使我给出一个很小的值作为参数,我的CPU使用率仍然很高。经过几次实验,它似乎是由多线程共享字段引起的 以下是我的代码(代码1)和实验: (代码2)最初我认为是shell命令使得使用率

我正在写一个小程序,使用一定比例的CPU。基本策略是,我将持续检查CPU使用情况,如果使用水平高于给定值,则使进程休眠

此外,由于我使用的是MacOS(不像Linux那样没有proc/stat,C#中没有PerformanceCounter),因此我必须在另一个线程中执行
top
命令,并从中获取CPU使用率

问题是,即使我给出一个很小的值作为参数,我的CPU使用率仍然很高。经过几次实验,它似乎是由多线程共享字段引起的

以下是我的代码(代码1)和实验:

(代码2)最初我认为是shell命令使得使用率非常高,因此我在
run()
中对无限循环进行了注释,只留下
getCpuUsage()
运行。然而,CPU使用率几乎为零

(代码3)然后,我编写了另一个独立于cpuUsage的
run()
函数,该函数打算使用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);
    }
}
void run(){
常数时钟时间=10;
常数时钟空闲时间=忙碌时间;
而(1){
时钟开始时间=时钟();
while(clock()-startTime
多线程C程序中的共享字段是否大量使用CPU


是的,多个CPU上的多个线程对共享内存位置的不断读/写会导致缓存线在CPU之间不断移动(缓存反弹)。在我看来,这是幼稚的“并行”中可伸缩性差的最重要原因应用程序。

好的。Code1创建一个线程,该线程以尽可能快的速度执行popen。因此,该线程占用所有cpu时间。另一个线程(主线程)执行usleep,但不执行popening线程

Code2还使用线程启动这个cpu,然后等待它完成(join),这是永远不会发生的

Code3运行一段时间,然后睡眠量相同,所以它应该消耗大约50%

所以基本上你应该做什么(如果你真的想用top实现这个目的),你调用它,然后睡眠1秒钟,或者100毫秒,看看你的code1主循环是否调整

while (1) {
    usleep (100*1000);
    out = popen(CPU_COMMAND, "r");

sleep不会停止线程的CPU使用。@marrownower但是我的代码的第三个版本运行良好,表明
usleep()
确实停止了CPU使用。顺便说一句,POSIX不允许多个控制线程同时读写内存位置-“应用程序应确保一个以上的控制线程(线程或进程)对任何内存位置的访问受到限制,这样,当另一个控制线程可能正在修改内存位置时,任何控制线程都无法读取或修改该内存位置。”
getUsage()
函数在
run()运行时保持不变
改变。因此代码2可以证明
getUsage()
不会占用太多cpu时间。