Thread: C programming histogram using Pthreads

  1. #1
    Registered User
    Join Date
    Apr 2014
    Posts
    2

    Unhappy how to get the correct order of execution of pthreads?

    I was doing Histogram using pthreads and after long struggle on it.. finally it says 'Segmentation Fault (Core Dumped)'. unfortunately I had this line p=(struct1 *)malloc(sizeof(struct1)); after getting the values to the struct variables from command line.. So that was cleared off.. Thanks for @DNT for letting me know that..
    Now when I try to execute the following program.. It sometimes displays the output and sometimes it is going out to the which_bin function and prints the following
    output type 1(which is not the correct output): Data = 0.000000 doesn't belong to a bin! Quitting
    output type 2(almost the correct output of histo with time taken by threads): 10.000-28.000: 28.000-46.000: 46.000-64.000: 64.000-82.000: 82.000-100.000: XXXXXXXXXX The code to be timed took 0.000415 seconds
    My ques is why the same prog when ran shows different outputs.. I am confused of what it is exactly looking for..
    Here is my code below..

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    #include "timer.h"
    void Usage(char prog_name[]);
    
    
    
    //void Get_args(void *p);
    void Gen_data(void *p);
    void Gen_bins(void *p);
    int Which_bin(void *p);
    void Print_histo(void *p);
    
    
    void func(void *p);
    
    struct test
    {
        int bin_count, i, bin;
        float min_meas, max_meas;
        float* bin_maxes;
        int* bin_counts;
        int data_count;
        float* data;
    };
    
    typedef struct test struct1;
    
    int main(int argc, char* argv[])
    {
        double start, finish, elapsed;
        GET_TIME(start);
    
        struct1 *p;
        pthread_t th1, th2, th3;
    
        p=(struct1 *)malloc(sizeof(struct1));
        if (argc != 5)
            Usage(argv[0]);
        p->bin_count = strtol(argv[1], NULL, 10);
        p->min_meas = strtof(argv[2], NULL);
        p->max_meas = strtof(argv[3], NULL);
        p->data_count = strtol(argv[4], NULL, 10);
    
        p->bin_maxes = malloc(p->bin_count*sizeof(float));
        p->bin_counts = malloc(p->bin_count*sizeof(int));
        p->data = malloc(p->data_count*sizeof(float));
    
    
        pthread_create(&th1,NULL,(void*) Gen_data,(void*) p);
        pthread_create(&th2,NULL,(void*) Gen_bins,(void*) p);
        pthread_create(&th3,NULL,(void*) func,(void*) p);
        printf("Hi\n");
    
    
        pthread_join(th1,NULL);
        pthread_join(th2,NULL);
        pthread_join(th3,NULL);
    
    
        Print_histo(p);
        free(p->data);
        free(p->bin_maxes);
        free(p->bin_counts);
    
        GET_TIME(finish);
        elapsed = finish - start;
        printf("The code to be timed took %f seconds\n", elapsed);
        return 0;
    }  /* main */
    
    void func(void *p)
    {
        int i;
        struct1 *args;
        args=(struct1*)p;
    
        for (i = 0; i < args->data_count; i++)
        {
            args->bin = Which_bin(args);
            args->bin_counts[args->bin]++;
        }
    
        #  ifdef DEBUG
            printf("bin_counts = ");
            for (i = 0; i < args->bin_count; i++)
                printf("%d ", args->bin_counts[i]);
            printf("\n");
        #  endif
    }
    
    /*---------------------------------------------------------------------
     * Function:  Usage
     * Purpose:   Print a message showing how to run program and quit
     * In arg:    prog_name:  the name of the program from the command line
     */
    void Usage(char prog_name[] /* in */)
    {
        fprintf(stderr, "usage: %s ", prog_name);
        fprintf(stderr, "<bin_count> <min_meas> <max_meas> <data_count>\n");
        exit(0);
    }  /* Usage */
    
    
    void Gen_data(void *p)
    {
        struct1 *args;
        args=(struct1*)p;
        int i;
        srandom(0);
        for (i = 0; i < args->data_count; i++)
            args->data[i] = args->min_meas + (args->max_meas - args->min_meas)*random()/((double) RAND_MAX);
    
        #ifdef DEBUG
            printf("data = ");
            for (i = 0; i < args->data_count; i++)
                printf("%4.3f ", args->data[i]);
            printf("\n");
        #endif
    } /* Gen_data */
    
    
    void Gen_bins(void* p)
    {
        struct1 *args;
        args=(struct1*)p;
        float bin_width;
        int   i;
        bin_width = (args->max_meas - args->min_meas)/args->bin_count;
    
        for (i = 0; i < args->bin_count; i++)
        {
            args->bin_maxes[i] = args->min_meas + (i+1)*bin_width;
            args->bin_counts[i] = 0;
        }
    
        #  ifdef DEBUG
            printf("bin_maxes = ");
            for (i = 0; i < args->bin_count; i++)
                printf("%4.3f ", args->bin_maxes[i]);
            printf("\n");
        #  endif
    }
    
    int Which_bin(void* p)
    {
        struct1 *args;
        args=(struct1*)p;
        int bottom = 0, top =  args->bin_count-1;
        int mid;
        float bin_max, bin_min;
    
        while (bottom <= top)
        {
            mid = (bottom + top)/2;
            bin_max = args->bin_maxes[mid];
            bin_min = (mid == 0) ? args->min_meas: args->bin_maxes[mid-1];
            if (*(args->data) >= bin_max)
                bottom = mid+1;
            else if (*(args->data) < bin_min)
                top = mid-1;
            else
                return mid;
        }
        fprintf(stderr, "Data = %f doesn't belong to a bin!\n", args->data);
        fprintf(stderr, "Quitting\n");
        exit(-1);
    }
    
    void Print_histo(void *p)
    {
        struct1 *args;
        args=(struct1*)p;
        int i, j;
        float bin_max, bin_min;
    
        for (i = 0; i < args->bin_count; i++)
        {
            bin_max = args->bin_maxes[i];
            bin_min = (i == 0) ? args->min_meas: args->bin_maxes[i-1];
            printf("%.3f-%.3f:\t", bin_min, bin_max);
            for (j = 0; j < args->bin_counts[i]; j++)
                printf("X");
            printf("\n");
        }
    }
    
    /* Print_histo */
    
    


    I would like to know if the program is logically wrong? if it is wrong logically in that case why is it showing the histogram output at times.. Thanks!
    Last edited by Deepak Mudiam; 04-24-2014 at 03:15 PM. Reason: to be clear on my ques.. i am editing my title

  2. #2
    Registered User
    Join Date
    Feb 2014
    Posts
    18
    I skimmed over your code quickly so I dont really know what it does. However you are passing the same struct to each thread, the threads subsequentally carry out the work. However acces to shared resources *should* always be coded in such a way that the resource you want to acces is not accesed at the same time by another thread.

    To do this pthread comes with something called a mutex. a mutex basically allows you to take explicit control over thread-synchronization.

    read this:
    https://computing.llnl.gov/tutorials/pthreads/

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault (core dumped) C programming pthreads
    By Deepak Mudiam in forum C Programming
    Replies: 2
    Last Post: 04-24-2014, 06:38 AM
  2. Histogram help
    By Fixxxer in forum C Programming
    Replies: 4
    Last Post: 11-12-2010, 02:15 AM
  3. histogram
    By bazzano in forum C Programming
    Replies: 3
    Last Post: 04-04-2007, 12:25 PM
  4. programming with pthreads in linux
    By kris.c in forum C Programming
    Replies: 4
    Last Post: 07-21-2006, 01:10 AM
  5. File input for histogram (programming)
    By Unregistered in forum C Programming
    Replies: 5
    Last Post: 07-22-2002, 08:26 PM

Tags for this Thread