【问题标题】:Thread affinity in Android with C programAndroid中的线程亲和性与C程序
【发布时间】:2014-02-28 15:23:56
【问题描述】:

我在线程关联方面遇到了奇怪的问题。我在 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。我试过了,但我得到了同样的结果。

【问题讨论】:

  • 您的内核很可能不允许用户空间程序修改亲和力。在这种情况下,您将需要驱动程序从您的进程中删除 PF_NO_SETAFFINITY 标志。
  • 感谢您的回答。我如何在我的流程中做到这一点?

标签: android c linux multithreading


【解决方案1】:

以下来自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 进行配置/构建。这似乎是您的程序无法设置线程亲和性以在您机器的其他内核上运行的原因。

您可能已经重新编译您的内核来实现这一点。

【讨论】:

  • 感谢您的回答。我在编译nexus 5内核时检查了默认选项,它具有下一个:“最大CPUS数= 4”和“多核调度程序支持”启用,所以问题不在这里。
猜你喜欢
  • 2017-12-06
  • 2013-04-25
  • 1970-01-01
  • 1970-01-01
  • 2011-01-15
  • 2012-11-07
  • 1970-01-01
相关资源
最近更新 更多