我对线程亲和力有奇怪的问题。我用C创建了一个程序:
#define _GNU_SOURCE
#include<stdio.h>
#include <sys/syscall.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include <time.h>
#include <errno.h>
#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
#define NANOS 1000000000LL
#define SIZE 1000
void* mesaureTime(void *cpu)
{
unsigned long i = 0;
int s;
cpu_set_t cpuset;
struct timespec start, end;
long elapsed;
pthread_t id = pthread_self();
CPU_ZERO(&cpuset);
CPU_SET(*(int *) cpu, &cpuset);
s = pthread_setaffinity_np(id, sizeof(cpu_set_t), &cpuset);
if (s != 0)
handle_error_en(s, "pthread_setaffinity_np");
if(pthread_equal(id,tid[0]))
printf("Realizando test...\n");
while(i<SIZE){
clock_gettime(CLOCK_MONOTONIC, &start);
// Do some calculation.
factorial(150000);
clock_gettime(CLOCK_MONOTONIC, &end);
arrayTimes[i] = elapsed;
elapsed = end.tv_nsec - start.tv_nsec + (end.tv_sec - start.tv_sec)*NANOS;
i++;
}
printf("Finished\n");
return 0;
}
int factorial(int a){
if (a==1){
return 1;
}else{
a=a*factorial(a-1);
}
return a;
}
int main(int argc, char *argv[])
{
int i = 0;
int err, result;
int *cpu_pointer;
int cpu = atoi(argv[1]);
cpu_pointer = &cpu;
err = pthread_create(&tid[i], NULL, mesaureTime, (void *) cpu_pointer);
if (err != 0)
printf("can't create thread :[%s]", strerror(err));
else
printf("Hilo de test creado satisfactoriamente\n");
pthread_join(tid[0], NULL);
printf("\n Finalizado el test\n");
return 0;
}
这个代码适用于带有Ubuntu的双核Intel CPU,但是当我使用arm-linux-gnueabi-gcc编译它并且我已经在我的Android设备(Nexus 4,Nexus 5和S4)中执行时,该程序无法在CPU 2,CPU 3或CPU 4中分配线程,它仅在CPU 1中工作.pthread_setaffinity_np函数始终返回CPU 2,3或4的错误(无效参数)。
我在这里阅读了一些问题Is it possible to set affinity with sched_setaffinity in Android?和Android set thread affinity。我试过了,但是我得到了同样的结果。
答案 0 :(得分:0)
manual关于此错误的以下说明:
EINVAL (pthread_setaffinity_np()) cpuset specified a CPU that was
outside the set supported by the kernel. (The kernel
configuration option CONFIG_NR_CPUS defines the range of the
set supported by the kernel data type used to represent CPU
sets.)
所以看起来您的当前内核已使用CONFIG_NR_CPUS = 1进行配置/构建。这似乎是您的程序无法为您的线程设置亲和力以在您的计算机的其他核心上运行的原因。
您可能需要重新编译内核才能实现此目的。