【问题标题】:Not able to find the bug in my multithreading program?在我的多线程程序中找不到错误?
【发布时间】:2016-05-25 05:29:44
【问题描述】:

我实现了一个简单的多线程程序,生产者访问全局变量并填充它,然后消费者打印它。

我主要是这样写的

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

我的 Producer 函数是这样的:

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

消费者函数是:

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
.........................................

经过一些回答和使用 mutex_cond_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 : 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

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

【问题讨论】:

  • 您需要一些机制来确保首先执行prod,然后它可以向cons 发送信号以打印该值。 ,, 想到一个pthread_cond_t 条件变量。它们用于线程在满足特定条件时相互发送信号(因此cons 可以等待,prod 可以打印然后接受用户输入,之后它可以向cons 发送信号以打印值然后停止。在@ 987654336@ 已打印,它可以向prod 发送信号以再次查询用户等)。这是一个很好的示例教程:computing.llnl.gov/tutorials/pthreads
  • 请注意:prodcons 函数不带参数。但他们should 采取void *。好像应该有警告
  • 你不应该在这里做你想做的事情。对于互斥锁,在 Pthread 手册中提到 如果线程尝试解锁未锁定的互斥锁或解锁的互斥锁,则会导致未定义的行为。 如果您需要实现生产者消费者同步,则应该使用pthread_cond_wait()pthread_cond_signal()

标签: c multithreading mutex


【解决方案1】:

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

初始值:mutex_full = NON_SIGNALEDmutex_empty = SIGNALED

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

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

【讨论】:

    【解决方案2】:

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

    https://computing.llnl.gov/tutorials/pthreads/#ConVarOverview

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

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

    【讨论】:

    • 信号量也是条件变量的一个很好的替代品。
    • @Martinn,我不同意你的观点,尤其是对于当前的问题。信号量是用于不同目的的不同同步对象。如果您想限制对某些资源的访问,这个很好。例如,您希望允许 10 个并发线程使用某个对象。
    • 是的,它们都可以使用。但在这个例子中,我更喜欢信号量。生产者可以为它创建的每个新数据增加信号量,这将指示消费者进行一个消费单元。这更好地匹配生产者/消费者设计模式。另外,当生产者的生产速度快于消费者的消费速度时会发生什么?来自您的消息来源:在调用 pthread_cond_wait() 之前调用 pthread_cond_signal() 是一个逻辑错误,这种情况可能会发生。
    • 我还是不同意你的看法。对不起,但你的例子也是错误的。如果生产者的生产速度快于消费者的处理速度,你仍然会丢失数据,因为在上面的例子中只有一个变量存储有效负载。一般来说,生产者应该在每次插入新值后将数据放入队列并发出 cond var 信号。消费者唤醒并处理队列中的 ALL 值。当队列为空时,他只是等待新的信号。
    猜你喜欢
    • 2021-07-01
    • 2023-03-20
    • 2012-02-21
    • 1970-01-01
    • 2013-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多