简体   繁体   中英

Pass an int array in pthread function in C

I'm coding a multithreaded program for exercise. Given an array (100 positions) of random numbers, I have to divide it by 5 arrays and give them to 5 pthreads in order to find the maximum and return these values to the main function that find the maximum between them. These is my code so far:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

#define NUM_THREADS 5
#define DIM_VETTORE 100


void *Calcola_max(void* args){


}



int main(){
    int vettore[DIM_VETTORE];
    int t;
    int i;
    srand(time(NULL));

/*riempio il vettore con numeri random*/
        for (i=0; i<DIM_VETTORE; i++){
        vettore[i]=rand() % 500 + 1;
        printf("Numero in posizione %d: %d\n", i,vettore[i]);
        }

/*indico le dimensioni di ogni array splittato*/
    int dimensione_split=DIM_VETTORE/NUM_THREADS;
    printf("Dimensione degli array splittati: %d\n", dimensione_split);

/*creo tutti i thread*/
        pthread_t thread[NUM_THREADS];
        for (t=0;t<NUM_THREADS; t++){
        printf("Main: creazione thread %d\n", t);
        int rc;

            rc=pthread_create(&thread[t], NULL, Calcola_max, &vettore);

                if (rc) {
                printf("ERRORE: %d\n", rc);
                exit(-1);
                }
        }
}

My question are: how can I split the array? And how can I pass each array to each pthread? Thanks in advance


So, I've edited my code but this time it gives me segmentation fault after the pthread creation. IMO I'm wrong to pass the argument of thread function in this way:

...   
pthread_create(&thread[t], NULL, Calcola_max, (void *)&start[i]);
...

void *Calcola_max(void *a){
...
s = *(int *)a;
...

Here is my entire code:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

#define NUM_THREADS 5
#define DIM_VETTORE 100
int vettore[DIM_VETTORE];
int    start[100];
int max[100];       //vettore dove vanno tutti i minimi calcolati dai pthread



void *Calcola_max(void *a){
    int array;
    int n=DIM_VETTORE/NUM_THREADS;
    int s, i;
    int start, stop;
    int massimo;

    s = *(int *)a;
    start = s * n;

    if ( s != (NUM_THREADS-1) )
   {
      stop = start + n;
   }
   else
   {
      stop = DIM_VETTORE;
   }
    massimo=vettore[start];

    for (i = start+1; i < stop; i++ )
   {


      if ( vettore[i] > massimo )
         massimo = vettore[i];
   }

   max[s] = massimo;



    //array = (int) a;

    int k;
    int max=0;  
        for (k=0; k<DIM_VETTORE; k++){      //qui devo mettere il range corrente del vettore, o mettere uno split di vettore
        printf("Massimo corrente: %d\n",max);
            if (vettore[k]>max) max=vettore[k];     
        }

//return(NULL);     /* Thread exits (dies) */   
pthread_exit;
}



int main(){
    //int vettore[DIM_VETTORE];
    int massimo;       //vettore dei minimi finale in cui opero confronto e calcolo il minimo
    int t;
    int i, j;
    srand(time(NULL));

/*riempio il vettore con numeri random*/
        for (i=0; i<DIM_VETTORE; i++){
        //int num;          //contenitore numero random
        vettore[i]=rand() % 500 + 1;
        //printf("Numero in posizione %d: %d\n", i,vettore[i]);
        }

/*indico le dimensioni di ogni array splittato*/
    int dimensione_split=DIM_VETTORE/NUM_THREADS;
    printf("Dimensione degli array splittati: %d\n", dimensione_split);

/*creo tutti i thread*/
        pthread_t thread[NUM_THREADS];
        for (t=0;t<NUM_THREADS; t++){
        start[i] = i;
        printf("Main: creazione thread %d\n", t);
        int rc;
        //int pos_vettore;
            //for (pos_vettore=0; pos_vettore<100; pos_vettore+20){
            rc=pthread_create(&thread[t], NULL, Calcola_max, (void *)&start[i]);

                if (rc) {
                printf("ERRORE: %d\n", rc);
                exit(-1);
                }
            //}
        }
        /*joino i threads*/
        for (i = 0; i < NUM_THREADS; i++)
      pthread_join(thread[i], NULL);

    massimo= max[0];
    sleep(3);
        for (i = 1; i < NUM_THREADS; i++)
                if ( max[i] > massimo )
            massimo = max[i];

    printf("Il massimo è: %d\n", massimo);


}

Your pthreads can access the array in your main program easily. You won't need to split the array for that. Just make sure that the pthreads are modifiying different parts of the main array. Use a struct or typedef to pass the relevant information to the pthread functions.

As mentioned, you don't split or copy the array.

Threads share the same regions of memory as the process that creates them, so you could just pass around the array.

If the aim of the game is to find some perf gain from using threads, then you almost certainly don't want to use heap allocated memory.

It's got to be said that there are probably better ways, I would probably look to SIMD or some other SSE extension before threads, but whatever ...

The following example , which has had about 5 minutes thought, and requires better error checking, and verification of the logic (because it's 9am on Sunday), demonstrates how I think the most efficient way to thread the calculations might be.

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <pthread.h>

#define THREADS 5
#define DATA 100

typedef struct _pthread_arg_t {
    pthread_t thread;
    int *data;
    unsigned int end;
    int max;
} pthread_arg_t;

void* pthread_routine(void *arg) {
    pthread_arg_t *info = (pthread_arg_t*) arg;
    int *it = info->data,
        *end = info->data + info->end;

    while (it < end) {
        if (*it > info->max) {
            info->max = *it;
        }
        it++;
    }

    pthread_exit(NULL);
}

int main(int argc, char *argv[]) {
    pthread_arg_t threads[THREADS];
    int data[DATA],
        thread = 0,
        limit = 0,
        result = 0;

    memset(&threads, 0, sizeof(pthread_arg_t) * THREADS);   
    memset(&data, 0, sizeof(int) * DATA);

    while (limit < DATA) {
        /* you can replace this with randomm number */
        data[limit] = limit;
        limit++;
    }

    limit = DATA/THREADS;

    while (thread < THREADS) {
        threads[thread].data = &data[thread * limit];
        threads[thread].end = limit;
        if (pthread_create(&threads[thread].thread, NULL, pthread_routine, &threads[thread]) != 0) {
            /* do something */
            return 1;
        }
        thread++;
    }

    thread = 0;
    while (thread < THREADS) {
        if (pthread_join(threads[thread].thread, NULL) != 0) {
            /* do something */
            return 1;
        }
        thread++;
    }

    thread = 0;
    result = threads[0].max;
    printf("result:\n");
    while (thread < THREADS) {
        printf("\t%d - %d: %d\n",
            thread * limit,
            thread * limit + limit - 1,
            threads[thread].max);
        if (threads[thread].max > result) {
            result = threads[thread].max;
        }
        thread++;
    }
    printf("max\t%d\n", result);

    return 0;
}

Notice that this is lock and malloc free, you could probably reduce instructions further with more fiddling ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM