CPU亲和掩码(将线程放在不同的CPU上)。

19 人关注

我有4个线程,我试图将线程1设置为在CPU 1上运行,线程2在CPU 2上运行,等等。 然而,当我运行下面的代码时,亲和掩码返回正确的值,但当我对线程进行sched_getcpu()时,它们都返回它们在CPU 4上运行。

有谁知道我这里的问题是什么?

提前感谢!

#define _GNU_SOURCE
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <sched.h>
#include <errno.h>
void *pthread_Message(char *message)
    printf("%s is running on CPU %d\n", message, sched_getcpu());
int main()
    pthread_t thread1, thread2, thread3, thread4;
    pthread_t threadArray[4];
    cpu_set_t cpu1, cpu2, cpu3, cpu4;
    char *thread1Msg = "Thread 1";
    char *thread2Msg = "Thread 2";
    char *thread3Msg = "Thread 3";
    char *thread4Msg = "Thread 4";
    int thread1Create, thread2Create, thread3Create, thread4Create, i, temp;
    CPU_ZERO(&cpu1);
    CPU_SET(1, &cpu1);
    temp = pthread_setaffinity_np(thread1, sizeof(cpu_set_t), &cpu1);
    printf("Set returned by pthread_getaffinity_np() contained:\n");
    for (i = 0; i < CPU_SETSIZE; i++)
        if (CPU_ISSET(i, &cpu1))
            printf("CPU1: CPU %d\n", i);
    CPU_ZERO(&cpu2);
    CPU_SET(2, &cpu2);
    temp = pthread_setaffinity_np(thread2, sizeof(cpu_set_t), &cpu2);
    for (i = 0; i < CPU_SETSIZE; i++)
        if (CPU_ISSET(i, &cpu2))
            printf("CPU2: CPU %d\n", i);
    CPU_ZERO(&cpu3);
    CPU_SET(3, &cpu3);
    temp = pthread_setaffinity_np(thread3, sizeof(cpu_set_t), &cpu3);
    for (i = 0; i < CPU_SETSIZE; i++)
        if (CPU_ISSET(i, &cpu3))
            printf("CPU3: CPU %d\n", i);
    CPU_ZERO(&cpu4);
    CPU_SET(4, &cpu4);
    temp = pthread_setaffinity_np(thread4, sizeof(cpu_set_t), &cpu4);
    for (i = 0; i < CPU_SETSIZE; i++)
        if (CPU_ISSET(i, &cpu4))
            printf("CPU4: CPU %d\n", i);
    thread1Create = pthread_create(&thread1, NULL, (void *)pthread_Message, thread1Msg);
    thread2Create = pthread_create(&thread2, NULL, (void *)pthread_Message, thread2Msg);
    thread3Create = pthread_create(&thread3, NULL, (void *)pthread_Message, thread3Msg);
    thread4Create = pthread_create(&thread4, NULL, (void *)pthread_Message, thread4Msg);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    pthread_join(thread3, NULL);
    pthread_join(thread4, NULL);
    return 0;
    
linux
multithreading
pthreads
parallel-processing
hwrd
hwrd
发布于 2010-04-02
3 个回答
Bahbar
Bahbar
发布于 2010-04-02
已采纳
0 人赞同

你在试图设置你没有初始化的线程的亲和力。

Edit: Ok, let me give you some more info:

不要把线程句柄(你存储在pthread_t变量中的东西)和它们所代表的东西(一个在某处运行的执行线程)混为一谈。你想做的是在一个线程开始前设置它的一个属性,而这个API需要线程对象。事实上,pthread_create在创建对象的同时也开始执行,所以试图使用 pthread_setaffinity_np 并不是正确的方法(如果你想要 变化 当前运行的线程的亲和力)。

但是......。替换代码1】有一个属性参数(你把NULL传给它)。这是在存储你希望线程如何被创建的信息。

亲和力是你可以通过该参数设置的属性之一。请参阅男人页文档中的 pthread_attr_init pthread_attr_setaffinity_np 对于究竟如何

hwrd
所以我必须先用pthread_create()来创建它们?但那已经运行了指定的函数......我不太确定我是否理解这整个概念。所以我应该把setaffinity函数放在我的pthread_Message()函数中?
你不需要让线程运行很长时间。 long 也就是说,它可能是新创建的线程做的第一件事。这将意味着,如果新的cpu掩码不包括其当前的cpu,它将被重新安排。
hwrd
我还是不明白...我想在pthread_create()之后,在pthread_create()调用的函数中设置亲和力掩码,还是在pthread_create()之前?
@hahuang65:我又补充了一些信息,希望对你有帮助。
John Samson
John Samson
发布于 2010-04-02
0 人赞同

这是你在寻找的东西。我知道这是个迟到的答案,但这可能有助于其他人。

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <sched.h>
#include <errno.h>
#include <unistd.h>
int   getNumberOfCpus( void )
    long nprocs       = -1;
    long nprocs_max   = -1;
    # ifdef _SC_NPROCESSORS_ONLN
    nprocs = sysconf( _SC_NPROCESSORS_ONLN );
    if ( nprocs < 1 )
        //std::cout << "Could not determine number of CPUs on line. Error is  " << strerror( errno ) << std::endl;
        return 0;
    nprocs_max = sysconf( _SC_NPROCESSORS_CONF );
    if ( nprocs_max < 1 )
        //std::cout << "Could not determine number of CPUs in host. Error is  " << strerror( errno ) << std::endl;
        return 0;
    //std::cout << nprocs < " of " << nprocs_max << " online" << std::endl;
    return nprocs; 
#else
    //std::cout << "Could not determine number of CPUs" << std::endl;
    return 0;
#endif
void *pthread_Message( void *ptr )
    sleep(10);
    char *message;
    message = (char *) ptr;
    printf("%s \n", message);
    cpu_set_t      l_cpuSet;
    int            l_maxCpus;
    int            j;
    unsigned long  l_cpuBitMask;
    CPU_ZERO( &l_cpuSet );
    printf("get affinity %d\n",pthread_getaffinity_np(pthread_self()  , sizeof( cpu_set_t ), &l_cpuSet ));
    // printf("cpuset %d\n",l_cpuSet);
    printf (" thread id %u\n", pthread_self());      
    if ( pthread_getaffinity_np(pthread_self()  , sizeof( cpu_set_t ), &l_cpuSet ) == 0 )
        for (int i = 0; i < 4; i++)
            if (CPU_ISSET(i, &l_cpuSet))
                printf("XXXCPU: CPU %d\n", i);
    for (long i=0; i< 10000000000; ++i);
int main()
    pthread_t thread1, thread2, thread3, thread4;
    pthread_t threadArray[4];
    cpu_set_t cpu1, cpu2, cpu3, cpu4;
    const char *thread1Msg = "Thread 1";
    const char *thread2Msg = "Thread 2";
    const char *thread3Msg = "Thread 3";
    const char *thread4Msg = "Thread 4";
    int thread1Create, thread2Create, thread3Create, thread4Create, i, temp;
    thread1Create = pthread_create(&thread1, NULL, &pthread_Message, (void*)thread1Msg);
    sleep(1);
    thread2Create = pthread_create(&thread2, NULL, &pthread_Message, (void*)thread2Msg);
    sleep(1);
    thread3Create = pthread_create(&thread3, NULL, &pthread_Message, (void*)thread3Msg);
    sleep(1);
    thread4Create = pthread_create(&thread4, NULL, &pthread_Message, (void*)thread4Msg);
    CPU_ZERO(&cpu1);
    CPU_SET(0, &cpu1);
    temp = pthread_setaffinity_np(thread1, sizeof(cpu_set_t), &cpu1);
    printf("setaffinity=%d\n", temp);
    printf("Set returned by pthread_getaffinity_np() contained:\n");
    for (i = 0; i < CPU_SETSIZE; i++)
        if (CPU_ISSET(i, &cpu1))
            printf("CPU1: CPU %d\n", i);
    CPU_ZERO(&cpu2);
    CPU_SET(1, &cpu2);
    temp = pthread_setaffinity_np(thread2, sizeof(cpu_set_t), &cpu2);
    for (i = 0; i < CPU_SETSIZE; i++)
        if (CPU_ISSET(i, &cpu2))
            printf("CPU2: CPU %d\n", i);
    CPU_ZERO(&cpu3);
    CPU_SET(2, &cpu3);
    temp = pthread_setaffinity_np(thread3, sizeof(cpu_set_t), &cpu3);
    for (i = 0; i < CPU_SETSIZE; i++)
        if (CPU_ISSET(i, &cpu3))
            printf("CPU3: CPU %d\n", i);
    CPU_ZERO(&cpu4);
    CPU_SET(3, &cpu4);
    temp = pthread_setaffinity_np(thread4, sizeof(cpu_set_t), &cpu4);
    for (i = 0; i < CPU_SETSIZE; i++)
        if (CPU_ISSET(i, &cpu4))
            printf("CPU4: CPU %d\n", i);
    // pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpu1);
    // pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpu1);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    pthread_join(thread3, NULL);
    pthread_join(thread4, NULL);