无法弄清楚为什么我没有从一个线程获取我作为输入的数组并尝试使用另一个线程打印它

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;
}

在线程 (pThread) 的帮助下,在生产者函数中,我获取了一个数组的用户输入,然后我尝试在 cThread 的帮助下,在消费者函数中打印相同的数组。但我只能打印数组的第一个元素。我需要进行哪些更改才能将整个数组作为输出?

你的问题的答案是你在创建新线程之前对线程执行 pthread_join() 。这意味着,您在启动新线程之前退出第一个线程。所以所有的操作都是完全串行的。

您应该启动这两个线程,然后按如下方式加入它们。

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);

但是你的代码还有一个问题。在 consumer() 函数中,您正在解锁 for 循环内的互斥量。我假设,您希望用户在生产者线程中读取来自用户的一个输入并在消费者线程中打印该输入值。在那种情况下,您必须将 mutex unlock 调用移到循环之外。请注意,pthread_cond_wait() 将在等待期间在内部解锁互斥量。此外,您需要在 pthread_cond_wait() 之后打印值,以确保用户输入了输入值。

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

我写这个答案只是为了下面有趣的部分!

调用pthread_create();对于线程并不意味着线程立即启动运行ning。多个线程可以 运行 随机(应该假定)顺序。

所以..如果消费者线程启动得非常晚,即如果它在生产者线程的两个或更多 pthread_cond_signal(&cond); 之后启动,那么消费者线程将进入死锁情况,因为它恰好 n 个 pthread_cond_wait()电话。请注意,如果没有线程在那个确切的时刻执行 pthread_cond_wait(),则会错过 pthread_cond_signal()

所以..在开始从生产者线程读取输入之前,您需要确保消费者线程已经启动。

有多种方法可以实现这一点。一种方法是使用全局标志和互斥锁进行轮询。 (您可以为此使用另一个互斥-条件-信号组合。)

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
}

现在,如果生产者先启动,它将在 while 循环中等待。如果消费者先启动,它将等待 pthread_cond_wait().

更新 1 根据下面的评论。

在 producer() 中,scanf() 在互斥锁中。它将无限期地阻止消费者。所以你可能无法正确获得输出。所以将 scanf() 放在锁外,如下所示。

 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);