multithreading CPU Affinity Masks(将线程放在不同的 CPU 上)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2563442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CPU Affinity Masks (Putting Threads on different CPUs)
提问by hahuang65
I have 4 threads, and I am trying to set thread 1 to run on CPU 1, thread 2 on CPU 2, etc. However, when I run my code below, the affinity masks are returning the correct values, but when I do a sched_getcpu() on the threads, they all return that they are running on CPU 4.
我有 4 个线程,我试图将线程 1 设置为在 CPU 1 上运行,将线程 2 设置为在 CPU 2 上运行,等等。但是,当我运行下面的代码时,关联掩码返回正确的值,但是当我执行sched_getcpu() ,它们都返回它们在 CPU 4 上运行。
Anybody know what my problem here is?
有人知道我这里的问题是什么吗?
Thanks in advance!
提前致谢!
#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;
}
采纳答案by Bahbar
You're trying to set the affinity of threads that you did not initialize.
您正在尝试设置未初始化的线程的亲和性。
Edit: Ok, let me give you some more info:
编辑:好的,让我给你一些更多的信息:
Don't mix thread handles (the thing you store in the pthread_t variable) and what they represent (a thread of execution that runs somewhere). What you were trying to do is to set a property of a thread before it starts, with an API that requires the thread object. As it happens pthread_create creates the object and starts the execution at the same time, so trying to use pthread_setaffinity_np
is not the right way to go (this is useful if you want to changethe affinity of a currently running thread).
不要混合线程句柄(您存储在 pthread_t 变量中的内容)和它们所代表的内容(在某处运行的执行线程)。您尝试做的是在线程启动之前使用需要线程对象的 API 设置线程的属性。碰巧 pthread_create 创建对象并同时开始执行,因此尝试使用pthread_setaffinity_np
不是正确的方法(如果您想更改当前正在运行的线程的亲和性,这很有用)。
But... pthread_create
has an attribute parameter (you're passing NULL to it). This is storing the information of how you want the thread to be created.
但是...pthread_create
有一个属性参数(您将 NULL 传递给它)。这是存储您希望如何创建线程的信息。
Affinity is one of the attributes you can set through that parameter. See the man-page documentation for pthread_attr_init
and pthread_attr_setaffinity_np
for how exactly
亲和力是您可以通过该参数设置的属性之一。请参阅手册页文档pthread_attr_init
,pthread_attr_setaffinity_np
了解具体方式
回答by John Samson
Here's what you were looking for. I know it is a late answer, but this might help others.
这就是你要找的。我知道这是一个迟到的答案,但这可能对其他人有所帮助。
#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;
}
回答by Nikolai Fetissov
I think the easiest would be to give the CPU mask as a parameter to each thread and have the thread request given affinity itself, as in example here: pthread_setaffinity_np(3)
.
我认为最简单的将是给CPU的面具作为参数传递给每个线程和有亲和力本身提供的线程请求,例如如在这里:pthread_setaffinity_np(3)
。