Kirix
Kirix

Reputation: 31

How to make 5 threads read and write array concurrently

I'm having an attempt at the famous producer-consumer problem in c++ and I have came up with an implementation like this...

#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <ctime>

void *consumeThread(void *i);
void *produceThread(void *i);

using std::cout;
using std::endl;
//Bucket size
#define Bucket_size 10

int buckets[Bucket_size];
pthread_mutex_t lock;
pthread_cond_t consume_now, produce_now;

time_t timer;

int o = 0;
int p = 0;

int main()
{
    int i[5] = {1, 2, 3, 4, 5};
    pthread_t consumer[5];
    pthread_t producer[5];

    pthread_mutex_init(&lock, nullptr);
    pthread_cond_init(&consume_now, nullptr);
    pthread_cond_init(&produce_now, nullptr);

    timer = time(nullptr) + 10;

    srand(time(nullptr));
    for (int x = 0; x < 5; x++)
    {
        pthread_create(&producer[x], nullptr, &produceThread, &i[x]);
    }

    for (int x = 0; x < 5; x++)
    {
        pthread_create(&consumer[x], nullptr, &consumeThread, &i[x]);
    }

    pthread_cond_signal(&produce_now);

    for (int x = 0; x < 5; x++)
    {
        pthread_join(producer[x], nullptr);
        pthread_join(consumer[x], nullptr);
    }

    pthread_mutex_destroy(&lock);
    pthread_cond_destroy(&consume_now);
    pthread_cond_destroy(&produce_now);

    return 0;
}

void *consumeThread(void *i)
{

    bool quit = false;

    while (!quit)
    {

        pthread_mutex_lock(&lock);
        pthread_cond_wait(&consume_now, &lock);

        printf("thread %d consuming element at array[%d] : the element is %d \n", *((int *)i), o, buckets[o]);
        buckets[o] = 0;
        p++;
        printArray();
        usleep(100000);

        pthread_cond_signal(&produce_now);
        pthread_mutex_unlock(&lock);

        quit = time(nullptr) > timer;
    }

    return EXIT_SUCCESS;
}

void *produceThread(void *i)
{

    int a = 0;
    bool quit = false;
    while (!quit)
    {

        o = p % 10;
        buckets[o] = (rand() % 20) + 1;
        printf("thread %d adding element in array[%d] : the element is %d \n", *((int *)i), o, buckets[o]);
        a++;
        printArray();
        usleep(100000);

        quit = time(nullptr) > timer;
    }
    return EXIT_SUCCESS;
}

currently this solution has 5 producer threads and 5 consumer threads, however it only lets 1 thread produce and 1 thread consume at a time, is there a way to make 5 of the producer and consumer threads work concurrently?

Example output from the program:
thread 1 adding element in array[0] : the element is 6
[6,0,0,0,0,0,0,0,0,0]

Upvotes: 1

Views: 110

Answers (1)

mevets
mevets

Reputation: 10435

Your first problem is that you are treating condition variables as if they have memory. In your main(), you pthread_cond_signal(), but at that point, you have no idea if any of your threads are waiting upon that condition. Since condition variables do not have memory, your signal may well be lost.

Your second problem is that o is effectively protected by the condition; since each consumer uses it; and each producer modifies it, you can neither permit multiple producers or consumers to execute concurrently.

Your desired solution amounts to a queue which you inject o's into from the producers; and collect them in the consumers. That way, your concurrency is gated by your ability to produce o's.

Upvotes: 3

Related Questions