我需要在创建线程之前设置亲缘关系(线程到核心,例如:第一个线程到第一个核心)。类似KMP_AFFINITY
中的OpenMP
。有可能吗?
编辑: 我试着用这种方式,但不要'工作:/
void* DoWork(void* args)
{
int nr = (int)args;
printf("Wątek: %d, ID: %d, CPU: %d\n", nr,pthread_self(), sched_getcpu());
}
int main()
{
int count = 8;
pthread_t threads[count];
pthread_attr_t attr;
cpu_set_t mask;
CPU_ZERO(&mask);
pthread_attr_init(&attr);
for (int i = 0; i < count ; i++)
CPU_SET(i, &mask);
pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &mask);
for(int i=0; i<count ; i++)
{
pthread_create(&threads[i], &attr, DoWork, (void*)i);
}
for(int i=0; i<count ; i++)
{
pthread_join(threads[i], NULL);
}
}
答案 0 :(得分:22)
如前所述,您应该使用pthread_attr_setaffinity_np
将线程绑定到特定核心。可以检索系统中可用的CPU核心数(请参阅下面的代码)。
在使用pthread_create
创建线程时,每次必须传递pthread_attr_t
的实例,该实例设置为适当的cpu_set_t
。每次必须清除cpu_set_t
或删除先前输入的数字(我选择前一个选项),然后再将下一个CPU核心标识符添加到集合中。如果要确定线程将在哪个CPU上执行,请在创建线程时在集合中只需要一个CPU(参见下面的代码)。
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void* DoWork(void* args) {
printf("ID: %lu, CPU: %d\n", pthread_self(), sched_getcpu());
return 0;
}
int main() {
int numberOfProcessors = sysconf(_SC_NPROCESSORS_ONLN);
printf("Number of processors: %d\n", numberOfProcessors);
pthread_t threads[numberOfProcessors];
pthread_attr_t attr;
cpu_set_t cpus;
pthread_attr_init(&attr);
for (int i = 0; i < numberOfProcessors; i++) {
CPU_ZERO(&cpus);
CPU_SET(i, &cpus);
pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpus);
pthread_create(&threads[i], &attr, DoWork, NULL);
}
for (int i = 0; i < numberOfProcessors; i++) {
pthread_join(threads[i], NULL);
}
return 0;
}
答案 1 :(得分:0)
您可以调用pthread_self()来获取主线程的线程ID,并在pthread_setaffinity_np中使用它。
答案 2 :(得分:0)
您可以使用pthread_attr_setaffinity_np
为pthread_create
功能设置亲和属性。