为什么系统监视器不显示正确的 CPU 关联?



我已经搜索了关于CPU相关性的问题/答案并阅读了结果,但我仍然无法将线程固定到单个CPU。

我正在开发一个将在专用linux盒子上运行的应用程序,所以我不关心其他进程,只关心我自己的进程。该应用程序当前生成一个pthread,然后主线程进入while循环,使用POSIX消息队列处理控制消息。这个while循环阻止等待控制消息进入,然后处理它。所以主线程非常简单,也不是关键的。我的代码运行得很好,因为我可以发送这个应用程序的消息,它会很好地处理它们。所有控制消息的大小都很小,仅用于控制应用程序的功能,也就是说,只发送/接收少数控制消息。

在进入while循环之前,我使用sched_getaffinity()来记录所有可用的CPU。然后我使用sched_setafinity()将这个进程设置为单个CPU。然后我再次调用sched_getaffinity()来检查它是否设置为仅在一个CPU上运行,并且它确实是正确的。

衍生出来的单个pthread也做了类似的事情。在新创建的pthread中,我要做的第一件事是调用pthread_getaffinity_np()并检查可用的CPU,然后调用pthread _setaffinity_npp()将其设置为不同的CPU,再调用pthreads_getaffinity _np(。

这就是令人困惑的地方。当我运行应用程序并在系统监视器中查看CPU历史记录时,我发现与在没有所有这些设置相关性的情况下运行应用程序时没有什么不同。在这个四核机箱上的4个CPU中,调度程序仍然在每个CPU中运行几秒钟。因此,调度程序似乎忽略了我的关联设置。

我期望看到一些证据来证明主线程和pthread实际上是在它们自己的单个CPU中运行的,这是不是错了??还是我忘了做更多的事情来让它按我的意愿运行?

谢谢,

-Andres

你没有答案,我会尽我所能:部分帮助

假设您检查了pthread_setaffinity_np:的返回值

如何分配cpuset非常重要,请在主线程中创建它。为了你想要的。它将传播到连续的线程。你检查过退货代码了吗?

您实际得到的cpuset将是硬件可用cpu和您定义的cpuset的交集。下面代码中的min.h是一个通用的构建包含文件。您必须定义_GNU_SOURCE-请注意,comment on the last line of the code. CPUSETCPUSETSIZE是宏。我想我在其他地方定义了它们,我不记得了。它们可能在标准标头中。

#define _GNU_SOURCE
#include "min.h"
#include <pthread.h>

int
main(int argc, char **argv)
{
    int s, j;
    cpu_set_t cpuset;
    pthread_t tid=pthread_self();
    // Set affinity mask to include CPUs 0 & 1
    CPU_ZERO(&cpuset);
    for (j = 0; j < 2; j++)
        CPU_SET(j, &cpuset);
    s = pthread_setaffinity_np(tid, sizeof(cpu_set_t), &cpuset);
    if (s != 0)
    {
        fprintf(stderr, "%d ", s);
        perror(" pthread_setaffinity_np");
        exit(1);
     }
     // lets see what we really have in the actual affinity mask assigned our thread
    s = pthread_getaffinity_np(tid, sizeof(cpu_set_t), &cpuset);
    if (s != 0)
    {
        fprintf(stderr, "%d ", s);
        perror(" pthread_setaffinity_np");
        exit(1);
     }
    printf("my cpuset has:n");
    for (j = 0; j < CPU_SETSIZE; j++)
        if (CPU_ISSET(j, &cpuset))
            printf("    CPU %dn", j);
    // @Andres note: any pthread_create call from here on creates a thread with the identical
    // cpuset - you do not have to call it in every thread.
    return 0;
}

最新更新