2010-04-01 3 views
16

4 개의 쓰레드가 있는데, 1 번 쓰레드를 CPU 1, 2 번 쓰레드 2 등에서 실행하려고합니다. 그러나 아래 코드를 실행할 때, 선호도 마스크는 올바른 값을 반환하지만 스레드에서 sched_getcpu()를 수행하면 CPU 4에서 실행 중임을 모두 반환합니다.CPU Affinity Masks (다른 CPU에 쓰레드 넣기)

아무도 내 문제가 무엇인지 알 수 있습니까? 사전에

감사합니다!

#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; 
} 

답변

16

초기화하지 않은 스레드의 선호도를 설정하려고합니다.

편집 : 좋아, 내가 당신에게 좀 더 많은 정보를 줄 수 있도록 :

는 그들이 대표 (당신이가 pthread_t 변수에 저장하는 것) 무엇을 (어디 실행 실행 스레드를) 스레드 핸들을 혼합하지 마십시오. 스레드 개체가 필요한 API를 사용하여 스레드가 시작되기 전에 스레드의 속성을 설정하려고했습니다. pthread_create는 객체를 생성하고 동시에 실행을 시작하므로 pthread_setaffinity_np을 사용하려고 시도하는 것은 올바른 방법이 아닙니다. 으로 변경하려는 경우 유용합니다. 현재 실행중인 스레드의 선호도를으로 변경하십시오.

... pthread_create에는 속성 매개 변수가 있습니다 (NULL을 전달하고 있음). 이것은 스레드 생성 방법에 대한 정보를 저장하는 것입니다.

선호도는 해당 매개 변수를 통해 설정할 수있는 특성 중 하나입니다. 방법에 대한 자세한 내용은 pthread_attr_initpthread_attr_setaffinity_np 설명서를 참조하십시오.

+0

그래서 먼저 pthread_create()해야합니다. 그러나 그것은 이미 지정된 함수를 실행합니다 ... 나는이 개념 전체를 이해할 수 있을지 너무 확신하지 못합니다. 그래서 내 pthread_Message() 함수에 setaffinity 함수를 넣어야합니까? – hahuang65

+0

매우 * long * 동안 스레드를 실행할 필요가 없습니다. 즉, 새로 생성 된 스레드가 가장 먼저 수행 할 수 있습니다. 이것은 새로운 CPU 마스크가 현재 CPU를 포함하지 않는다면 다시 일정이 잡히는 것을 의미합니다. – MarkR

+0

아직도 이해가 안 ... pthread_create(), pthread_create()가 호출하는 함수 또는 pthread_create() 전에 Diffing을 사용하여 선호도 마스크를 설정하고 싶습니다. – hahuang65

2

가장 간단한 방법은 CPU 마스크를 각 스레드에 대한 매개 변수로 제공하고 여기에 예제와 같이 스레드 요청을 지정하는 것입니다. pthread_setaffinity_np(3).

+0

내 스레드 (thread1, thread2, thread3 또는 thread4) 중 pthread_self()를 호출하는 스레드를 어떻게 알 수 있습니까? – hahuang65

+0

저는 Bahbar가 이미 이것을 대답했다고 생각합니다 - thread 함수 매개 변수를 사용하십시오. 스레드 매개 변수는 실제로 스레드를 가리키는 affinity mask를 포함하는 구조체를 말합니다. 작업자 스레드간에 동일한 구조체 인스턴스를 공유하지 않도록 조심하십시오. –

4

다음은 귀하가 찾고 있었던 것입니다. 나는 그것이 늦은 대답이라는 것을 알고 있지만 이것은 다른 사람들에게 도움이 될 수 있습니다.

#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); 

    return 0; 
}