Thread: Producer-Consumer problem

  1. #1
    Registered User
    Join Date
    Nov 2012
    Posts
    6

    Producer-Consumer problem

    I am trying to get this to run, but I am having a problem with it telling me I have an undefined reference to _imp_pthread_create and _imp_pthread_exit at multiple locations. Starting with line 122. I can't figure it out.

    Code:
    #include <iostream>#include <fstream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <cmath>
    #include <ctime>
    #include <iomanip>
    #include <vector>
    #include <string>
    
    
    #include <pthread.h>
    
    
    using namespace std;
    
    
    struct Date
    {
        int day; //1-30
        int month; //1-12
        int year; //06
    };
    
    
    struct Item
    {
            Date SalesDate;
        int storeID; //1-p
        int registerNum; //1-10
        double saleAmount; // 0.50 – 999.99
    };
    
    
    void *produce(void *threadid); //function for producer processes
    void *consume(void *threadid); //function for consumer processes
    void cwait(int& S, int threadid, vector<int>& waiting, double l_Aggregate, double l_Store_Wide[], double l_Month_Wise[]); //wait semaphore function for consumers
    void pwait(int& S, int threadid, vector<int>& waiting); //wait semaphore function for producers
    void signal(int& S); //signal semaphore function
    void printStatistics(double l_Aggregate, double l_Store_Wide[], double l_Month_Wise[], int threadid); //function where consumers print local statistics
    Item produceItem(void *t); //function for production of new items with random values
    
    
    //SHARED VARIABLES
    
    
    int numOfRecords, numOfRecordsRead, in, out; //variables for counting records produced, counting records consumed, and determining where to add or remove items from the buffer
    int p, c, b; //number of producers, consumers, and buffer size
    int empty, full, mutex; //semaphores
    
    
    vector<int> ewaiting; //waiting queue for empty semaphore
    vector<int> fwaiting; //waiting queue for full semaphore
    vector<int> mwaiting; //waiting queue for mutex semaphore
    int consumersDone; //flag vector for indicating when producer/consumer threads are finished executing
    vector<Item> buffer;
    vector<double> Store_Wide; //Store-wide total sales
    double Month_Wise[12]; //Month-wise total sales (in all stores)
    double Aggregate; // Aggregate sales (all sales together)
    double Time; //Total time for simulation (from begin to end)
    
    
    int main(int argc, char** argv)
    {
        //start time
        srand(time(NULL));
        clock_t start, stop;
        start = clock() + CLK_TCK;
    
    
        ifstream inFile;
    
    
        string fileName = argv[1];
    
    
        inFile.open(fileName.c_str());
    
    
        inFile >> p >> c >> b;
    
    
        inFile.close();
    
    
        // BEGIN INITIALIZATIONS
    
    
        Item emptyItem;
        emptyItem.SalesDate.day = 0;
        emptyItem.SalesDate.month = 0;
        emptyItem.SalesDate.year = 0;
        emptyItem.storeID = 0;
        emptyItem.registerNum = 0;
        emptyItem.saleAmount =  0;
    
    
        for (int i = 0; i < b; i++)
        {
            buffer.push_back(emptyItem);
        }
    
    
        bool allConsumersDone = false;
    
    
        numOfRecords = 0;
        numOfRecordsRead = 0;
        in = 0;
        out = 0;
    
    
        empty = b;
        full = 0;
        mutex = 1;
    
    
        Aggregate = 0;
    
    
        consumersDone = 0;
    
    
        for (int i = 0; i < p; i++)
        {
            Store_Wide.push_back(0);
        }
    
    
        for (int i = 0; i < 12; i++)
        {
            Month_Wise[i] = 0;
        }
    
    
        // END INITIALIZATIONS
    
    
        //BEGIN THREAD CREATION
    
    
        pthread_t p_threads[p], c_threads[c];
    
    
    int rc, t;
    
    
    for(t=1; t < (p+1); t++)
    {
        rc = pthread_create(&p_threads[t], NULL, produce, (void *)t);
    
    
        if (rc)
        {
            printf("ERROR; return code from pthread_create() is %d\n", rc);
            exit(-1);
        }
    }
    
    
    for(t=1+p; t < (c+p+1); t++)
    {
          rc = pthread_create(&c_threads[t], NULL, consume, (void *)t);
    
    
            if (rc)
            {
                printf("ERROR; return code from pthread_create() is %d\n", rc);
                exit(-1);
            }
        }
    
    
        //END THREAD CREATION
    
    
        while (!allConsumersDone) //main waits until producer/consumer threads are finished executing
        {
            if (consumersDone == c)
                allConsumersDone = true;
        };
    
    
        //print global statistics and time
    
    
        cout << "GLOBAL STATISTICS" << endl;
        cout << "Global Aggregate: " << Aggregate << endl;
    
    
        cout << "Global Store Wide" << endl;
        for (int i = 0; i < p; i++)
        {
            cout << "Store ID: " << (i + 1) << endl;
            cout << "Global Sales: " << Store_Wide[i] << endl;
        }
    
    
        cout << "Global Month Wise" << endl;
        for (int i = 0; i < 12; i++)
        {
            cout << "Month: " << (i + 1) << endl;
            cout << "Global Sales: " << Month_Wise[i] << endl;
        }
    
    
        stop = clock()+CLK_TCK;
        Time = ((double) stop-start)/1000;
        cout << "Runtime: " << Time << " seconds" << endl << endl;
    
    
        pthread_exit(NULL);
        return 0;
    }
    
    
    void *produce(void *threadid) //production thread function
    {
        while (numOfRecords < 50)
        {
            Item nextProduced = produceItem(threadid); //produce item
    
    
            pwait(empty, (int) threadid, ewaiting);
            pwait(mutex, (int) threadid, mwaiting);
    
    
            //add item to buffer
    
    
            buffer[in] = nextProduced;
            in = ( in + 1) % b;
    
    
            numOfRecords++;
    
    
            signal(mutex);
            signal(full);
    
    
            int sleepTime = rand() % 36 + 5;
    //        sleep(sleepTime); //sleep for 5-40 ms
        }
        pthread_exit(NULL);
    }
    
    
    void *consume(void *threadid) //consumption thread function
    {
        double l_Store_Wide[p]; //Store-wide total sales (LOCAL)
        double l_Month_Wise[12]; //Month-wise total sales (in all stores) (LOCAL)
        double l_Aggregate = 0; // Aggregate sales (all sales together) (LOCAL)
    
    
        //initialize above variables
    
    
        for (int i = 0; i < p; i++)
        {
            l_Store_Wide[i] = 0;
        }
    
    
        for (int i = 0; i < 12; i++)
        {
            l_Month_Wise[i] = 0;
        }
    
    
        while (numOfRecordsRead < 50)
        {
            cwait(full, (int) threadid, fwaiting, l_Aggregate, l_Store_Wide, l_Month_Wise);
            cwait(mutex, (int) threadid, mwaiting, l_Aggregate, l_Store_Wide, l_Month_Wise);
    
    
            //remove item from buffer to nextConsumed
    
    
            Item nextConsumed = buffer[out];
    
    
            //create blank item to replace consumed item in buffer
    
    
            Item emptyItem;
            emptyItem.SalesDate.day = 0;
            emptyItem.SalesDate.month = 0;
            emptyItem.SalesDate.year = 0;
            emptyItem.storeID = 0;
            emptyItem.registerNum = 0;
            emptyItem.saleAmount =  0;
    
    
            buffer[out] = emptyItem;
            out = (out + 1) % b;
            numOfRecordsRead++;
    
    
            signal(mutex);
            signal(empty);
    
    
            //consume item in nextConsumed/ record statistics
            l_Aggregate = l_Aggregate + nextConsumed.saleAmount;
            l_Store_Wide[nextConsumed.storeID - 1] = l_Store_Wide[nextConsumed.storeID - 1] + nextConsumed.saleAmount;
            l_Month_Wise[nextConsumed.SalesDate.month - 1] = l_Month_Wise[nextConsumed.SalesDate.month - 1] + nextConsumed.saleAmount;
        }
    
    
        //print local statistics
    
    
        printStatistics(l_Aggregate, l_Store_Wide, l_Month_Wise, (int) threadid);
    }
    
    
    void cwait(int& S, int threadid, vector<int>& waiting, double l_Aggregate, double l_Store_Wide[], double l_Month_Wise[])
    {
        waiting.push_back((int)threadid);
        while (S <= 0 || waiting[0] != threadid)
        {
            if (numOfRecordsRead >= 50)
                printStatistics(l_Aggregate, l_Store_Wide, l_Month_Wise, threadid); //print local statistics
        };
        S--;
        waiting.erase(waiting.begin());
    }
    
    
    void pwait(int& S, int threadid, vector<int>& waiting)
    {
        waiting.push_back((int)threadid);
        while (S <= 0 || waiting[0] != threadid)
        {
            if (numOfRecords >= 50)
                pthread_exit(NULL); //terminate thread
        };
        S--;
        waiting.erase(waiting.begin());
    }
    
    
    void signal(int& S)
    {
        S++;
    }
    
    
    Item produceItem(void *t)
    {
        Item newItem;
        newItem.SalesDate.day = rand() % 30 + 1;
        newItem.SalesDate.month = rand() % 12 + 1;
        newItem.SalesDate.year = 6;
        newItem.storeID = (int) t; //producerThreadID
        newItem.registerNum = rand() % 10 + 1;
        newItem.saleAmount =  static_cast<double>( rand() ) * 999.49 / static_cast<double>( RAND_MAX ) + 0.5 ; // rand() * range / RAND_MAX + low
    
    
        return newItem;
    }
    
    
    void printStatistics(double l_Aggregate, double l_Store_Wide[], double l_Month_Wise[], int threadid)
    {
        cout << "LOCAL STATISTICS" << endl;
        cout << "Consumer ID: " << threadid << endl;
        cout << "Local Aggregate: " << l_Aggregate << endl;
        Aggregate = Aggregate + l_Aggregate;
    
    
        cout << "Local Store Wide" << endl;
        for (int i = 0; i < p; i++)
        {
            cout << "Store ID: " << (i + 1) << endl;
            cout << "Local Sales: " << l_Store_Wide[i] << endl;
            Store_Wide[i] = Store_Wide[i] + l_Store_Wide[i];
        }
    
    
        cout << "Local Month Wise" << endl;
        for (int i = 0; i < 12; i++)
        {
            cout << "Month: " << (i + 1) << endl;
            cout << "Local Sales: " << l_Month_Wise[i] << endl;
            Month_Wise[i] = Month_Wise[i] + l_Month_Wise[i];
        }
    
    
        consumersDone++;
    
    
        pthread_exit(NULL);
    }

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Please post your complete error messages, exactly as they appear in your development environment.

    Here are a list of errors I received when I tried to compile your code:
    main.cpp||In function ‘int main(int, char**)’:|
    main.cpp|69|error: ‘CLK_TCK’ was not declared in this scope|
    main.cpp|143|error: ISO C++ forbids variable length array ‘p_threads’ [-Wvla]|
    main.cpp|143|error: ISO C++ forbids variable length array ‘c_threads’ [-Wvla]|
    main.cpp|64|warning: unused parameter ‘argc’ [-Wunused-parameter]|
    main.cpp||In function ‘void* produce(void*)’:|
    main.cpp|243|warning: unused variable ‘sleepTime’ [-Wunused-variable]|
    main.cpp||In function ‘void* consume(void*)’:|
    main.cpp|252|error: ISO C++ forbids variable length array ‘l_Store_Wide’ [-Wvla]|
    main.cpp|316|warning: no return statement in function returning non-void [-Wreturn-type]|
    ||=== Build finished: 4 errors, 3 warnings ===|
    Jim

  3. #3
    Registered User
    Join Date
    Nov 2012
    Posts
    6
    Here are the errors that I ran into.
    obj\Debug\main.o||In function `main':|
    C:\Users\mmiketa\Desktop\producerConsumer\main.cpp |122|undefined reference to `_imp__pthread_create'|
    C:\Users\mmiketa\Desktop\producerConsumer\main.cpp |133|undefined reference to `_imp__pthread_create'|
    C:\Users\mmiketa\Desktop\producerConsumer\main.cpp |173|undefined reference to `_imp__pthread_exit'|
    obj\Debug\main.o||In function `Z7producePv':|
    C:\Users\mmiketa\Desktop\producerConsumer\main.cpp |199|undefined reference to `_imp__pthread_exit'|
    obj\Debug\main.o||In function `Z5pwaitRiiRSt6vectorIiSaIiEE':|
    C:\Users\mmiketa\Desktop\producerConsumer\main.cpp |275|undefined reference to `_imp__pthread_exit'|
    obj\Debug\main.o||In function `Z15printStatisticsdPdS_i':|
    C:\Users\mmiketa\Desktop\producerConsumer\main.cpp |324|undefined reference to `_imp__pthread_exit'|
    ||=== Build finished: 6 errors, 0 warnings ===|


    If I run it in a different compiler, Dev-CPP, I get similar errors:
    [Linker error] undefined reference to `__dyn_tls_init_callback'
    [Linker error] undefined reference to `__cpu_features_init'
    [Linker error] undefined reference to `_imp__pthread_create'
    [Linker error] undefined reference to `_imp__pthread_create'
    [Linker error] undefined reference to `_imp__pthread_exit'
    [Linker error] undefined reference to `_imp__pthread_exit'
    [Linker error] undefined reference to `_imp__pthread_exit'
    [Linker error] undefined reference to `_imp__pthread_exit'
    ld returned 1 exit status
    Last edited by mistereff; 11-28-2012 at 10:50 AM. Reason: additional information

  4. #4
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    It appears that you are not linking with the pthread library.


    Jim

  5. #5
    Registered User
    Join Date
    Nov 2012
    Posts
    6
    How exactly would I fix that? I have been looking at this code for over an hour and I can't seem to fix it. I tried searching for linker problems but got nothing.

  6. #6
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    What compiler/IDE are you using?

    Jim

  7. #7
    Registered User
    Join Date
    Nov 2012
    Posts
    6
    I tried on both DevCPP and on CodeBlocks

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    I recommend you stick with CodeBlocks, it is much more up to date.

    To add a library to the project in CodeBlocks right click on your project in the Management window and select Build Options. At this point you should be on the Compiler Flags tab. This would be a good time to increase your compiler error levels. After you select all the C++ specific warnings you will need to select the linker settings tab and then select Add under the Link Libraries window. Then add the pthread library, you will probably want to search for it using the ... icon.

    Jim

  9. #9
    Registered User
    Join Date
    Nov 2012
    Posts
    6
    Thank you! I got that running but now I am having multiple problems. This is what I need:

    The statistics to be maintained are:Store-wide total sales
    Month-wise total sales (in all stores)
    Aggregate sales (all sales together)
    Total time for simulation (from begin to end)
    Each producer produces records randomly. Assume that the DD field is 1-30, MM is 01-
    12, and YY is always 06. Store IDs are in the 1 to p range (where p is the number of
    producers). The register numbers range from 1-10 for any store. The sale amount in each
    item can range between 0.50 and 999.99. Each producer generates its record with random
    data. Run the program until 10,000 items are produced by all producers together.
    Obviously, the number of items produced so far (by all producers) need to be maintained
    in shared memory. Each producer is assigned a fixed store ID when it is created. It has
    the following structure:
    But I do not know how to get to that point. This is my current code:

    Code:
    #include <iostream>#include <fstream>
    #include <stdio.h>
    #include <pthread.h>
    #include <stdlib.h>
    #include <time.h>
    #include <cmath>
    #include <ctime>
    #include <iomanip>
    #include <vector>
    #include <string>
    
    
    
    
    #include <pthread.h>
    
    
    using namespace std;
    
    
    const double CLK_TCK = 1000.0;
    
    
    struct Date
    {
        int day; //1-30
        int month; //1-12
        int year; //06
    };
    
    
    struct Item
    {
            Date SalesDate;
        int storeID; //1-p
        int registerNum; //1-10
        double saleAmount; // 0.50 – 999.99
    };
    
    
    void *produce(void *threadid); //function for producer processes
    void *consume(void *threadid); //function for consumer processes
    void cwait(int& S, int threadid, vector<int>& waiting, double l_Aggregate, double l_Store_Wide[], double l_Month_Wise[]); //wait semaphore function for consumers
    void pwait(int& S, int threadid, vector<int>& waiting); //wait semaphore function for producers
    void signal(int& S); //signal semaphore function
    void printStatistics(double l_Aggregate, double l_Store_Wide[], double l_Month_Wise[], int threadid); //function where consumers print local statistics
    Item produceItem(void *t); //function for production of new items with random values
    
    
    //SHARED VARIABLES
    
    
    int numOfRecords, numOfRecordsRead, in, out; //variables for counting records produced, counting records consumed, and determining where to add or remove items from the buffer
    int p, c, b; //number of producers, consumers, and buffer size
    int empty, full, mutex; //semaphores
    
    
    vector<int> ewaiting; //waiting queue for empty semaphore
    vector<int> fwaiting; //waiting queue for full semaphore
    vector<int> mwaiting; //waiting queue for mutex semaphore
    int consumersDone; //flag vector for indicating when producer/consumer threads are finished executing
    vector<Item> buffer;
    vector<double> Store_Wide; //Store-wide total sales
    double Month_Wise[12]; //Month-wise total sales (in all stores)
    double Aggregate; // Aggregate sales (all sales together)
    double Time; //Total time for simulation (from begin to end)
    
    
    int main(int argc, char** argv)
    {
        //start time
        srand(time(NULL));
        clock_t start, stop;
        start = clock() + CLK_TCK;
    
    
        ifstream inFile;
    
    
       // string fileName = argv[1];
    
    
        inFile.open("testfile.txt");
    
    
        cin >> p >> c >> b;
    
    
        inFile.close();
    
    
        // BEGIN INITIALIZATIONS
    
    
        Item emptyItem;
        emptyItem.SalesDate.day = 0;
        emptyItem.SalesDate.month = 0;
        emptyItem.SalesDate.year = 0;
        emptyItem.storeID = 0;
        emptyItem.registerNum = 0;
        emptyItem.saleAmount =  0;
    
    
        for (int i = 0; i < b; i++)
        {
            buffer.push_back(emptyItem);
        }
    
    
        bool allConsumersDone = false;
    
    
        numOfRecords = 0;
        numOfRecordsRead = 0;
        in = 0;
        out = 0;
    
    
        empty = b;
        full = 0;
        mutex = 1;
    
    
        Aggregate = 0;
    
    
        consumersDone = 0;
    
    
        for (int i = 0; i < p; i++)
        {
            Store_Wide.push_back(0);
        }
    
    
        for (int i = 0; i < 12; i++)
        {
            Month_Wise[i] = 0;
        }
    
    
        // END INITIALIZATIONS
    
    
        //BEGIN THREAD CREATION
    
    
        pthread_t p_threads[p], c_threads[c];
    
    
        int rc, t;
    
    
        for(t=1; t < (p+1); t++)
        {
            rc = pthread_create(&p_threads[t], NULL, produce, (void *)t);
    
    
            if (rc)
            {
                printf("ERROR; return code from pthread_create() is %d\n", rc);
                exit(-1);
            }
        }
    
    
        for(t=1+p; t < (c+p+1); t++)
        {
            rc = pthread_create(&c_threads[t], NULL, consume, (void *)t);
    
    
            if (rc)
            {
                printf("ERROR; return code from pthread_create() is %d\n", rc);
                exit(-1);
            }
        }
    
    
        //END THREAD CREATION
    
    
        while (!allConsumersDone) //main waits until producer/consumer threads are finished executing
        {
            if (consumersDone == c)
                allConsumersDone = true;
        };
    
    
        //print global statistics and time
    
    
        cout << "GLOBAL STATISTICS" << endl;
        cout << "Global Aggregate: " << Aggregate << endl;
    
    
        cout << "Global Store Wide" << endl;
        for (int i = 0; i < p; i++)
        {
            cout << "Store ID: " << (i + 1) << endl;
            cout << "Global Sales: " << Store_Wide[i] << endl;
        }
    
    
        cout << "Global Month Wise" << endl;
        for (int i = 0; i < 12; i++)
        {
            cout << "Month: " << (i + 1) << endl;
            cout << "Global Sales: " << Month_Wise[i] << endl;
        }
    
    
        stop = clock()+CLK_TCK;
        Time = ((double) stop-start)/1000;
        cout << "Runtime: " << Time << " seconds" << endl << endl;
    
    
        pthread_exit(NULL);
        return 0;
    }
    
    
    void *produce(void *threadid) //production thread function
    {
        while (numOfRecords < 50)
        {
            Item nextProduced = produceItem(threadid); //produce item
    
    
            pwait(empty, *(int*) threadid, ewaiting);
            pwait(mutex, *(int*) threadid, mwaiting);
    
    
            //add item to buffer
    
    
            buffer[in] = nextProduced;
            in = ( in + 1) % b;
    
    
            numOfRecords++;
    
    
            signal(mutex);
            signal(full);
    
    
    
    
            int sleepTime = rand() % 36 + 5;
        //(sleepTime); //sleep for 5-40 ms
        }
        pthread_exit(NULL);
    }
    
    
    void *consume(void *threadid) //consumption thread function
    {
        double l_Store_Wide[p]; //Store-wide total sales (LOCAL)
        double l_Month_Wise[12]; //Month-wise total sales (in all stores) (LOCAL)
        double l_Aggregate = 0; // Aggregate sales (all sales together) (LOCAL)
    
    
        //initialize above variables
    
    
        for (int i = 0; i < p; i++)
        {
            l_Store_Wide[i] = 0;
        }
    
    
        for (int i = 0; i < 12; i++)
        {
            l_Month_Wise[i] = 0;
        }
    
    
        while (numOfRecordsRead < 50)
        {
            cwait(full, *(int*) threadid, fwaiting, l_Aggregate, l_Store_Wide, l_Month_Wise);
            cwait(mutex, *(int*) threadid, mwaiting, l_Aggregate, l_Store_Wide, l_Month_Wise);
    
    
            //remove item from buffer to nextConsumed
    
    
            Item nextConsumed = buffer[out];
    
    
            //create blank item to replace consumed item in buffer
    
    
            Item emptyItem;
            emptyItem.SalesDate.day = 0;
            emptyItem.SalesDate.month = 0;
            emptyItem.SalesDate.year = 0;
            emptyItem.storeID = 0;
            emptyItem.registerNum = 0;
            emptyItem.saleAmount =  0;
    
    
            buffer[out] = emptyItem;
            out = (out + 1) % b;
            numOfRecordsRead++;
    
    
            signal(mutex);
            signal(empty);
    
    
            //consume item in nextConsumed/ record statistics
            l_Aggregate = l_Aggregate + nextConsumed.saleAmount;
            l_Store_Wide[nextConsumed.storeID - 1] = l_Store_Wide[nextConsumed.storeID - 1] + nextConsumed.saleAmount;
            l_Month_Wise[nextConsumed.SalesDate.month - 1] = l_Month_Wise[nextConsumed.SalesDate.month - 1] + nextConsumed.saleAmount;
        }
    
    
        //print local statistics
    
    
        printStatistics(l_Aggregate, l_Store_Wide, l_Month_Wise, *(int*) threadid);
    }
    
    
    void cwait(int& S, int threadid, vector<int>& waiting, double l_Aggregate, double l_Store_Wide[], double l_Month_Wise[])
    {
        waiting.push_back((int)threadid);
        while (S <= 0 || waiting[0] != threadid)
        {
            if (numOfRecordsRead >= 50)
                printStatistics(l_Aggregate, l_Store_Wide, l_Month_Wise, threadid); //print local statistics
        };
        S--;
        waiting.erase(waiting.begin());
    }
    
    
    void pwait(int& S, int threadid, vector<int>& waiting)
    {
        waiting.push_back((int)threadid);
        while (S <= 0 || waiting[0] != threadid)
        {
            if (numOfRecords >= 50)
                pthread_exit(NULL); //terminate thread
        };
        S--;
        waiting.erase(waiting.begin());
    }
    
    
    void signal(int& S)
    {
        S++;
    }
    
    
    Item produceItem(void *t)
    {
        Item newItem;
        newItem.SalesDate.day = rand() % 30 + 1;
        newItem.SalesDate.month = rand() % 12 + 1;
        newItem.SalesDate.year = 6;
        newItem.storeID = *(int*) t; //producerThreadID
        newItem.registerNum = rand() % 10 + 1;
        newItem.saleAmount =  static_cast<double>( rand() ) * 999.49 / static_cast<double>( RAND_MAX ) + 0.5 ; // rand() * range / RAND_MAX + low
    
    
        return newItem;
    }
    
    
    void printStatistics(double l_Aggregate, double l_Store_Wide[], double l_Month_Wise[], int threadid)
    {
        cout << "LOCAL STATISTICS" << endl;
        cout << "Consumer ID: " << threadid << endl;
        cout << "Local Aggregate: " << l_Aggregate << endl;
        Aggregate = Aggregate + l_Aggregate;
    
    
        cout << "Local Store Wide" << endl;
        for (int i = 0; i < p; i++)
        {
            cout << "Store ID: " << (i + 1) << endl;
            cout << "Local Sales: " << l_Store_Wide[i] << endl;
            Store_Wide[i] = Store_Wide[i] + l_Store_Wide[i];
        }
    
    
        cout << "Local Month Wise" << endl;
        for (int i = 0; i < 12; i++)
        {
            cout << "Month: " << (i + 1) << endl;
            cout << "Local Sales: " << l_Month_Wise[i] << endl;
            Month_Wise[i] = Month_Wise[i] + l_Month_Wise[i];
        }
    
    
        consumersDone++;
    
    
        pthread_exit(NULL);
    
    
    }
    
    The code was edited to work with CodeBlocks on Ubuntu. Now I get a segmentation fault.
    Last edited by mistereff; 11-29-2012 at 01:04 PM.

  10. #10
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Your "semaphores" are completely broken. You need to use the synchronization primitives provided by the threading library - pthreads in this case.
    Use a pthread_mutex_t as a generic lock for mutually exclusive access.
    Use a pthread_cond_t to block one or more threads on a predicate condition.

    Here is an example of a simple producer-consumer Q to get you started: Probably very easy question about pthread mutexes

    gg

  11. #11
    Registered User
    Join Date
    Nov 2012
    Posts
    6
    Was your example in C? Would it work the same in C++?

  12. #12
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> Was your example in C? Would it work the same in C++?
    Yes and yes.

    Here's a C++ example using boost: Boost thread request queue design question

    gg

  13. #13
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    on linux, at least, you pass the -pthread parameter to the compiler, and it knows to link the pthreads library. not sure if that works on windows.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Producer Consumer concurrency problem
    By Kurjack in forum C Programming
    Replies: 0
    Last Post: 10-18-2010, 02:21 PM
  2. Producer/Consumer Problem
    By AvengedGoat in forum C++ Programming
    Replies: 5
    Last Post: 03-21-2010, 12:33 PM
  3. Lists for producer/consumer problem
    By radeberger in forum C++ Programming
    Replies: 0
    Last Post: 03-29-2009, 12:57 PM
  4. pthread producer consumer problem
    By Amit Chikorde in forum C Programming
    Replies: 1
    Last Post: 01-17-2007, 07:39 PM
  5. Producer consumer problem
    By traz in forum C Programming
    Replies: 2
    Last Post: 11-08-2002, 08:04 PM