0

My code doesn't seem to work the way I want, I have tried to find where the problem is but I just can't seem to see that there's something wrong with it ...I think I may have understood the whole thing wrong. I am trying to set the affinity of a thread,I want to make it run on a specific cpu,then when I run it and display the value of sched_getcpu() it's not the correct value,not the cpu I forced my thread to run on.

#define _GNU_SOURCE
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sched.h>
#include <sys/wait.h>

void *fonction(void *arg){
    int n=(int)arg;
    int res=1;
    int i;      
    for(i=2;i<=n;i++) res=res*i;

    fprintf(stderr,"calculating %d! by cpu %d\n",n,sched_getcpu());
    sleep(5);
    return (void*)res;
}
int main(int argc, char *argv[]){
    pthread_t *threads=NULL;
    cpu_set_t cpuset;
    void *retour;
    pthread_attr_t attr;
    int cpu;
    int ar;
    int val;
    int numcpu=sysconf(_SC_NPROCESSORS_ONLN);
    if(sscanf(argv[1],"%d",&ar)!=1){
        fprintf(stderr,"error\n");
        exit(EXIT_FAILURE);
    }   
    threads=calloc(numcpu,sizeof(pthread_t));
    if(threads==NULL){
        fprintf(stderr,"calloc error\n");
        exit(EXIT_FAILURE);
    }
    for(cpu=0;cpu<numcpu;cpu++){
        val=ar-cpu;
        pthread_attr_init(&attr);
        CPU_ZERO(&cpuset);
        CPU_SET(cpu,&cpuset);
        if(pthread_create(&threads[cpu],&attr,fonction,(void*)val)!=0){
            fprintf(stderr,"problem creating thread\n");
            exit(EXIT_FAILURE);
        }
        if(pthread_attr_setaffinity_np(&attr,sizeof(cpu_set_t),&cpuset)!=0){
            fprintf(stderr,"error setting affinity\n");
            exit(EXIT_FAILURE);
        }
        pthread_join(threads[cpu],&retour);
        fprintf(stderr,"%d!=%d done by %d\n",val,(int)retour,cpu);
    }

    free(threads);
    pthread_exit(NULL);
    return 0;
}

the execution gives this

flora
  • 47
  • 5
  • Please don't post screen shots of text output. Include the text directly in the question (treat it like code; if you're feeling fancy, add `` on a line on its own before the output, but no-one should criticize you for not including that). – Jonathan Leffler Dec 14 '17 at 00:43
  • Never access beyond `argv[0]` without first checking `argc` to confirm that the desired command line parameter has actually been entered by the user. – user3629249 Dec 14 '17 at 01:33
  • regarding this kind of statement: `fprintf(stderr,"calloc error\n");` when a system function fails and returns an error indication, should also output (to stderr) the associated text that indicates why the system thinks the error occurred. The best function to handle all this is `perror()` – user3629249 Dec 14 '17 at 01:35
  • to avoid a memory leak, after the call to `calloc()`, any following call to `exit( EXIT_FAILURE );` needs to be preceded by `free( threads );` – user3629249 Dec 14 '17 at 01:39
  • @user3629249: Actually, call to `exit` *automatically* releases some types of resources, and memory heap among them. Some programmers prefer to explicitely call `free()` in any case, but this is not required. – Tsyvarev Dec 14 '17 at 07:24
  • 1
    As for the problem: `pthread_create` creates a thread according to **current** content of **attributes**, that is without affinity. Futher modifications of `attr` by calling `pthread_attr_setaffinity_np` has no effect on already created thread. – Tsyvarev Dec 14 '17 at 07:36
  • 1
    thanks,I have forgotten that pthread_attr_setafinity_np is for setting affinity of a thread which is not yet created.I have placed this statement before the pthread_create statement and it works well.it was a good hint thanks – flora Dec 14 '17 at 11:55

0 Answers0