简体   繁体   中英

Not able to figure out why am i not getting the array that i took as input from one thread and trying to print it using another

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

pthread_mutex_t mutex;
pthread_cond_t cond;
void *producer(void *arg);
void *consumer(void *arg);
int buffer[100];
static int n;

void *producer(void *arg) {   //`For taking user input`
int i;
printf("\n Enter the Array of %d terms",n);

for (i = 0; i < n; i++) 
{
 pthread_mutex_lock(&mutex);
 scanf(" %d\n",&buffer[i]);

 pthread_cond_signal(&cond);
 pthread_mutex_unlock(&mutex);
}
}

void *consumer(void *arg) {  // For printing the input array
int i;

printf("\nConsumer Function"); 
pthread_mutex_lock(&mutex);
for (i = 0; i < n; i++) 
{

printf("%d\n",buffer[i]);         
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);

}
}

int main()
{
int i=0;
pthread_mutex_init(&mutex, 0);
pthread_cond_init(&cond, 0);

pthread_t pThread, cThread;

printf("\n Enter no of terms");
scanf("%d",&n);

pthread_create(&pThread, 0, producer, 0);
pthread_join(pThread,NULL);  
pthread_create(&cThread, 0, consumer,0);   
pthread_join(cThread, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}

In the producer function with the help of thread (pThread) I took user input for an array and then I tried to print the same array in the consumer function with the help of cThread. But I am only able to print just the first element of the array. What are the changes that I need to make so that I can get the whole array as output?

Answer to your question is you are doing pthread_join() for a thread before creating new thread. It means, you are exiting the first thread before starting new thread. So all operations are completely serial.

You should start both the threads and then join them as below.

pthread_create(&pThread, 0, producer, 0); //Check return value and handle error
pthread_create(&cThread, 0, consumer,0);  //Check return value and handle error  
pthread_join(pThread,NULL);
pthread_join(cThread, NULL);

But there is one more issue in you code. In consumer() function you are unlocking mutex inside for loop. I assume, you want user to read one input from user in producer thread and print that input value in consumer thread. In that case you have to move mutex unlock call outside the loop. Please note that, pthread_cond_wait() will internally unlock the mutex during wait. Also, you need to print value after pthread_cond_wait() to ensure that user has entered an input value.

pthread_mutex_lock(&mutex);
for (i = 0; i < n; i++) 
{
    pthread_cond_wait(&cond, &mutex);
    printf("%d\n",buffer[i]);    
}
pthread_mutex_unlock(&mutex);

I have written this answer just for the interesting part below!

Calling pthread_create(); for a thread does not mean that the thread starts running immediately. Multiple threads can run in a random (should be assumed) order.

So.. If consumer thread starts very late ie if it starts after two or more pthread_cond_signal(&cond); from producer thread, then consumer thread will enter deadlock situation as it does exact n number of pthread_cond_wait() calls. Please note that, a pthread_cond_signal() is missed if no thread is doing pthread_cond_wait() at that exact time instant.

So.. you need to ensure that consumer thread has started before start reading input from producer thread.

There are multiple ways to achieve this. One way is to poll using a global flag and mutex. (You can use another mutex-condition-signal combination for this.)

void *producer(void *arg) { 
    while(1) {
        pthread_mutex_lock(&mutex);
        if(1 == consumerStartedFlag) {
            pthread_mutex_unlock(&mutex);
            break;
        }
        pthread_mutex_unlock(&mutex);
        usleep(1000); //Sleep for 1ms to prevent this thread from consuming large CPU
    }

    //Rest of the producer functionality
}


void *consumer(void *arg) {  // For printing the input array

    pthread_mutex_lock(&mutex);
    consumerStartedFlag = 1; //Global flag, intialize it to zero in main before starting threads.
    pthread_mutex_unlock(&mutex);

    //Rest of the consumer functionality
}

Now, if producer starts first, it will wait in while loop. If consumer starts first, it will wait in pthread_cond_wait() .

Update 1 Based on a comment below.

In producer(), scanf() is inside mutex lock. It will block the consumer indefinately. So you may not get the output properly. So Put scanf() outside lock as below.

 scanf(" %d",&buffer[i]); //Remove '\n' from scanf() as it will block your scanf call.
 pthread_mutex_lock(&mutex);
 pthread_cond_signal(&cond);
 pthread_mutex_unlock(&mutex);

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