C 无法在我的多线程程序中找到错误?

C 无法在我的多线程程序中找到错误?,c,multithreading,mutex,C,Multithreading,Mutex,我已经实现了一个简单的多线程程序,生产者在consumner打印后访问全局变量并填充它 我写的主要内容是这样的 #include<stdio.h> #include<stdlib.h> #include<pthread.h> void *prod(void); void *cons(void); unsigned int my_var = 0; pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; int m

我已经实现了一个简单的多线程程序,生产者在consumner打印后访问全局变量并填充它

我写的主要内容是这样的

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

void *prod(void);
void *cons(void);

unsigned int my_var = 0;

pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;

int main()
{
    pthread_t th1, th2;
    int status;

    status = pthread_create(&th1, NULL, (void*)prod, NULL);
    if(status)
    {
        printf("Error creating thread 1 : %d\n", status);
        exit(-1);
    }
    status = pthread_create(&th2, NULL, (void*)cons, NULL);
    if(status)
    {
         printf("Error creating thread 2 : %d\n", status);
         exit(-1);
    }

    pthread_join(th1, NULL);
    pthread_join(th2, NULL);

    return 0;
}
消费者功能是:

void *cons(void)
{
    while(1)
    {
        printf("The value entered was %d\n", my_var);
        pthread_mutex_lock(&mut);
    }
}
此程序以精确的输出运行,但模式不同,如:

Enter the value : The value entered was 0
The value entered was 0
45
Enter the value : The value entered was 45
85
Enter the value : The value entered was 85
12
Enter the value : The value entered was 12
67
Enter the value : The value entered was 67
49
Enter the value : The value entered was 49
我发现很难纠正这种逻辑,因为我是线程概念的新手。 请帮我解决这个问题

我的预期产出:

Enter the value : 45
The value entered is 45
.........................................
Enter the value : 78
Enter the value : The value entered was 78
86
Enter the value : 15
Enter the value : The value entered was 15
35
Enter the value : 86
Enter the value : The value entered was 86
12
Enter the value : 65
Enter the value : The value entered was 65
78
Enter the value : 65
Enter the value : The value entered was 65
12
Enter the value : 35
Enter the value : The value entered was 35
在给出了一些使用互斥锁的答案和指导原则之后,我在函数中使用了它们,如下所示:

void *prod(void)
{
    while(1)
    {
        pthread_mutex_unlock(&mut);
        printf("Enter the value : ");
        scanf("%d", &my_var);
    }
}
void *prod(void)
{
    while(1)
    {
        printf("Enter the value : ");
        scanf("%d", &my_var);
        pthread_cond_signal(&condition_var1);
        pthread_mutex_unlock(&mut);
    }  
}

void *cons(void)
{
    while(1)
    {
        pthread_mutex_lock(&mut);
        pthread_cond_wait( &condition_var1, &mut );
        printf("The value entered was %d\n", my_var);
    }
}
结果输出:

Enter the value : 45
The value entered is 45
.........................................
Enter the value : 78
Enter the value : The value entered was 78
86
Enter the value : 15
Enter the value : The value entered was 15
35
Enter the value : 86
Enter the value : The value entered was 86
12
Enter the value : 65
Enter the value : The value entered was 65
78
Enter the value : 65
Enter the value : The value entered was 65
12
Enter the value : 35
Enter the value : The value entered was 35

请指导我清理代码以获得预期的输出。

从逻辑上讲,生产者代码可能会在消费者有机会运行之前运行多次。在这种情况下,您可能会丢失一些输入的值。您将需要2个互斥锁
mutex\u full
mutex\u empty

初始值:
mutex\u full=无信号
mutex\u empty=有信号

Producer()
{
Wait(mutex_empty);
//produce code
Signal(mutex_full);
}

Consumer()
{
Wait(mutex_full);
//consumer code
Signal(mutex_empty);
}

我建议在这种情况下使用条件变量

这种方法对您的任务更有效。所以消费者应该等待一些条件变量。当生产者获得新数据时,他将通知条件变量,消费者将醒来处理这些数据


上面的链接有很好的解释,但是如果您有问题,欢迎您

您需要一些机制来确保首先执行
prod
,然后它可以发出信号
cons
,以打印值,,我想到了一个
pthread\u cond\t
条件变量。它们用于线程在满足特定条件时相互发送信号(因此
cons
可以等待,
prod
可以打印,然后接受用户输入,之后可以发送信号
cons
打印值,然后停止。在
cons
打印后,可以发送信号
prod
再次查询用户,等等)。这是一个很好的示例教程:只需注意:
prod
cons
函数不带参数。但是他们采取了
void*
。似乎应该有一个警告:你不应该做你在这里想做的事。对于互斥体,Pthread手册中提到,如果线程尝试解锁未锁定的互斥体或已解锁的互斥体,则会导致未定义的行为。如果您需要实现生产者-消费者同步,您应该使用
pthread\u cond\u wait()
pthread\u cond\u signal()
。信号量也是条件变量的一个很好的替代品。@martin,我不同意您的观点,尤其是对于当前问题。信号量是用于不同目的的不同同步对象。如果您想限制对某些资源的访问,那么这个选项很好。例如,您希望允许10个线程同时使用某个对象。是的,它们都可以使用。但在这个例子中,我更喜欢信号量。生产者可以为其创建的每一个新数据增加信号量,这将向消费者发出一个消费单元的信号。这更符合生产者/消费者的设计模式。当生产者的生产速度快于消费者的消费速度时,又会发生什么呢?从您的来源:在调用pthread_cond_wait()之前调用pthread_cond_signal()是一个逻辑错误,这种情况可能会发生。我仍然不同意您的看法。对不起,你的例子也错了。。若生产者的生产速度快于消费者的处理速度,那个么您仍然会丢失数据,因为在上面的示例中,只有一个变量存储有效负载。通常,生产者应在每次插入新值后将数据放入队列并发出cond var信号。消费者唤醒并处理队列中的所有值。当队列变空时,他只是等待新的信号。