C 多个生产者和消费者,但一个共享资源-只有一个线程正在运行

C 多个生产者和消费者,但一个共享资源-只有一个线程正在运行,c,multithreading,qt,producer-consumer,C,Multithreading,Qt,Producer Consumer,在这里,我创建了2个生产者线程和2个消费者线程。它们只在一个共享队列中放入和取出值 问题是,第一个生产者确实填写了,然后进入等待模式 在此之后,没有其他线程运行。请解释一下我遗漏了什么 #include "mainwindow.h" #include <QApplication> #include <pthread.h> #include <stdio.h> #include <unistd.h> #include <sys/syscall

在这里,我创建了2个生产者线程和2个消费者线程。它们只在一个共享队列中放入和取出值

问题是,第一个生产者确实填写了,然后进入等待模式

在此之后,没有其他线程运行。请解释一下我遗漏了什么

#include "mainwindow.h"
#include <QApplication>

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <iostream>
#include <QDebug>


pthread_mutex_t mutexVariable     = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  conditionVariable = PTHREAD_COND_INITIALIZER;

int numberOfActiveProducers;
int numberOfActiveConsumers;

QList <int> sharedQueue;
/*
 * `sharedQueue`'s size is assumed to be 10 ATM.
 * `sharedQueue` is supposed to be shared among two threads.
 * Producer threads will put the 1's in it, and Consumer threads will remove the 1's.
 * Assumption: `sharedQueue` can contain only 10 elements at a time.
 */

int sizeOfSharedQueue;

//  This function is run by the thread `Producer A`.
void *threadProducerAFunction (void *arg) {
    Q_UNUSED (arg);

    while (1) {
        qDebug () << "\nProducer A";

        pthread_mutex_lock (&mutexVariable);

        if (sharedQueue.length () < 10) {
            sharedQueue.push_back (1);
            qDebug () << "\nPushed by Producer A: Length of queue is: " << sharedQueue.length ();
        }
        else {
            qDebug () << "\nProducer A has done its bit and is now in waiting mode. Length of queue is: " << sharedQueue.length ();
            pthread_cond_wait (&conditionVariable, &mutexVariable);
        }

        pthread_mutex_unlock (&mutexVariable);
    }

    return NULL;
}

//  This function is run by the thread `ProducerB`.
void *threadProducerBFunction (void *arg) {
    Q_UNUSED (arg);

    while (1) {
        qDebug () << "\nProducer B";

        pthread_mutex_lock (&mutexVariable);

        if (sharedQueue.length () < 10) {
            sharedQueue.push_back (1);
            qDebug () << "\nPushed by Producer B: Length of queue is: " << sharedQueue.length ();
        }
        else {
            qDebug () << "\nProducer B has done its bit and is now in waiting mode. Length of queue is: " << sharedQueue.length ();
            pthread_cond_wait (&conditionVariable, &mutexVariable);
        }

        pthread_mutex_unlock (&mutexVariable);
    }

    return NULL;
}

//  This function is run by the thread `Consumer A`.
void *threadConsumerAFunction (void *arg) {
    Q_UNUSED (arg);

    while (1) {
        qDebug () << "\nConsumer A";

        pthread_mutex_lock (&mutexVariable);

        if (sharedQueue.length () > 0) {
            sharedQueue.pop_front ();
            qDebug () << "\nRemoved by thread Consumer A. Length of queue is: " << sharedQueue.length ();
        }
        else {
            pthread_cond_signal (&conditionVariable);
            qDebug () << "\nSignal issued by thread Consumer A. Length of queue is: " << sharedQueue.length ();
        }

        pthread_mutex_unlock (&mutexVariable);
    }   
    return NULL;
}

//  This function is run by the thread `Consumer B`.
void *threadConsumerBFunction (void *arg) {
    Q_UNUSED (arg);

    while (1) {
        qDebug () << "\nConsumer B";

        pthread_mutex_lock (&mutexVariable);

        if (sharedQueue.length () > 0) {
            sharedQueue.pop_front ();
            qDebug () << "\nRemoved by thread Consumer B. Length of queue is: " << sharedQueue.length ();
        }
        else {
            pthread_cond_signal (&conditionVariable);
            qDebug () << "\nSignal issued by thread Consumer B. Length of queue is: " << sharedQueue.length ();
        }

        pthread_mutex_unlock (&mutexVariable);
    }
    return NULL;
}

int main (int argc, char *argv[]) {
    numberOfActiveProducers = 2;
    numberOfActiveConsumers = 2;
    sizeOfSharedQueue       = 10;

    // `sharedQueue` initialization by 0.
    for (int i = 0; i < sizeOfSharedQueue; i++) {
        sharedQueue.push_back (0);
    }

    // Producer threads creation and joining
    pthread_t producerA;
    pthread_t producerB;

    if (pthread_create (&producerA, NULL, threadProducerAFunction, NULL)) {
        fprintf (stderr, "Error creating thread Producer A\n");
        return 1;
    }

    if (pthread_join (producerA, NULL)) {
        fprintf (stderr, "Error joining thread Producer A\n");
        return 2;
    }

    if (pthread_create (&producerB, NULL, threadProducerBFunction, NULL)) {
        fprintf (stderr, "Error creating thread Producer A\n");
        return 1;
    }

    if (pthread_join (producerB, NULL)) {
        fprintf (stderr, "Error joining thread Producer B\n");
        return 2;
    }

    // Consumer threads creation and joining
    pthread_t consumerA;
    pthread_t consumerB;

    if (pthread_create (&consumerA, NULL, threadConsumerAFunction, NULL)) {
        fprintf (stderr, "Error creating thread Consumer A\n");
        return 1;
    }

    if (pthread_join (consumerA, NULL)) {
        fprintf (stderr, "Error joining thread Consumer A\n");
        return 2;
    }

    if (pthread_create (&consumerB, NULL, threadConsumerBFunction, NULL)) {
        fprintf (stderr, "Error creating thread Consumer B\n");
        return 1;
    }

    if (pthread_join (consumerB, NULL)) {
        fprintf (stderr, "Error joining thread Consumer B\n");
        return 2;
    }

    QApplication a (argc, argv);
    MainWindow w;
    w.show ();

    return a.exec ();
}
#包括“mainwindow.h”
#包括
#包括
#包括
#包括
#包括
#包括
#包括
pthread_mutex_t mutexVariable=pthread_mutex_初始值设定项;
pthread_cond_t conditionVariable=pthread_cond_初始值设定项;
国际生产商协会;
int numberofactiveconsumer;
QList共享队列;
/*
*“sharedQueue”的大小假定为10个ATM。
*'sharedQueue'应该在两个线程之间共享。
*生产者线程将把1放入其中,消费者线程将删除1。
*假设:`sharedQueue`一次只能包含10个元素。
*/
int-sizeOfSharedQueue;
//此函数由线程“Producer A”运行。
void*threadproducera函数(void*arg){
Q_未使用(arg);
而(1){

qDebug()问题是在每次
pthread\u create
call in
main
pthread\u join
调用后都会有
pthread\u join
调用,根据定义,直到等待退出的线程才会被阻塞。由于没有子线程退出,因此第一次
pthread\u join
调用将被彻底阻塞,并且因此,不会执行后续的
pthread\u create
调用

一种修复方法是删除所有的
pthread\u join
调用。
pthread\u join
通常用于等待并获取子线程的返回状态,或者同步主线程,使其在子线程完成之前不会退出。因此,在这种情况下实际上不需要这些
pthread\u join
调用因为子线程不退出,而主线程调用执行阻止其退出任务的
a.exec()


与实际问题无关,但我发现您基本上复制了每个线程的生产者和消费者代码。这是不必要的,因为相同的线程函数可以传递给多个
pthread\u create
调用(只要没有静态变量)。如果要出于调试目的区分实例,请使用线程id或将不同的
arg
传递给每个线程进行标识。

问题是,根据定义,在每个
pthread\u create
调用
main
pthread\u join
之后都会有
pthread\u join
调用锁定等待退出的线程。由于没有子线程退出,因此第一个
pthread\u join
调用将被无限阻塞,因此不会执行后续的
pthread\u create
调用

一种修复方法是删除所有的
pthread\u join
调用。
pthread\u join
通常用于等待并获取子线程的返回状态,或者同步主线程,使其在子线程完成之前不会退出。因此,在这种情况下实际上不需要这些
pthread\u join
调用因为子线程不退出,而主线程调用执行阻止其退出任务的
a.exec()


与实际问题无关,但我发现您基本上复制了每个线程的生产者和消费者代码。这是不必要的,因为相同的线程函数可以传递给多个
pthread\u create
调用(只要没有静态变量)。如果要区分实例以进行调试,请使用线程id或将不同的
arg
传递给每个线程以进行标识。

您正在混合框架

如果您已经在使用
Qt
,那么它附带了一系列线程类,使您的生活更加轻松

我已将您的代码转换为等价的
Qt
代码,它工作正常

#include <QtCore/qthread.h>
#include <QtWidgets/QApplication>
#include <QtCore/qmutex.h>
#include <QtCore/qwaitcondition.h>
#include <QtCore/QList.h>
#include <QtCore/qdebug.h>

QMutex mutex;
QWaitCondition waitCondition;

int numberOfActiveProducers;
int numberOfActiveConsumers;

QList<int> sharedQueue;

class Producer : public QThread{
public:
    Producer(QString const &label) : label(label) {}

    void run() {
        forever {
            qDebug() << QString("\nProducer %1").arg(label);

            QMutexLocker locker(&mutex);

            if (sharedQueue.length() < 10){
                sharedQueue << 1;
                qDebug() << QString("\nPushed by Producer %1: Length of queue is: %2").arg(label).arg(sharedQueue.length());
            } else {
                qDebug() << QString("\nProducer %1 has done its job and is now in waiting mode. Length of queue is: %2").arg(label).arg(sharedQueue.length());
                waitCondition.wait(&mutex);
            }
        }
    }

private:
    QString label;
};

class Consumer : public QThread{
public:
    Consumer(QString const &label) : label(label) {}

    void run(){
        forever {
            qDebug() << QString("\nConsumer %1").arg(label);

            QMutexLocker locker(&mutex);

            if (sharedQueue.length() > 0){
                sharedQueue.takeFirst();
                qDebug() << QString("\nRemoved by thread Consumer %1. Length of queue is: %2").arg(label).arg(sharedQueue.length());
            } else {
                waitCondition.wakeAll();
                qDebug() << QString("\nSignal issued by thread Consumer %1. Length of queue is: %2").arg(label).arg(sharedQueue.length());
            }
        }
    }

private:
    QString label;
};

int main(int argc, char **argv){
    numberOfActiveConsumers = 2;
    numberOfActiveProducers = 2;

    QCoreApplication a(argc, argv);

    Producer producerA("A");
    Producer producerB("B");
    Consumer consumerA("A");
    Consumer consumerB("B");

    producerA.start();
    producerB.start();
    consumerA.start();
    consumerB.start();

    return a.exec();
}
#包括
#包括
#包括
#包括
#包括
#包括
QMutex互斥;
QWaitCondition-waitCondition;
国际生产商协会;
int numberofactiveconsumer;
QList共享队列;
类生产者:公共QThread{
公众:
生产者(QString常量和标签):标签(标签){}
无效运行(){
永远{

qDebug()您正在混合框架

如果您已经在使用
Qt
,那么它附带了一系列线程类,使您的生活更加轻松

我已将您的代码转换为等价的
Qt
代码,它工作正常

#include <QtCore/qthread.h>
#include <QtWidgets/QApplication>
#include <QtCore/qmutex.h>
#include <QtCore/qwaitcondition.h>
#include <QtCore/QList.h>
#include <QtCore/qdebug.h>

QMutex mutex;
QWaitCondition waitCondition;

int numberOfActiveProducers;
int numberOfActiveConsumers;

QList<int> sharedQueue;

class Producer : public QThread{
public:
    Producer(QString const &label) : label(label) {}

    void run() {
        forever {
            qDebug() << QString("\nProducer %1").arg(label);

            QMutexLocker locker(&mutex);

            if (sharedQueue.length() < 10){
                sharedQueue << 1;
                qDebug() << QString("\nPushed by Producer %1: Length of queue is: %2").arg(label).arg(sharedQueue.length());
            } else {
                qDebug() << QString("\nProducer %1 has done its job and is now in waiting mode. Length of queue is: %2").arg(label).arg(sharedQueue.length());
                waitCondition.wait(&mutex);
            }
        }
    }

private:
    QString label;
};

class Consumer : public QThread{
public:
    Consumer(QString const &label) : label(label) {}

    void run(){
        forever {
            qDebug() << QString("\nConsumer %1").arg(label);

            QMutexLocker locker(&mutex);

            if (sharedQueue.length() > 0){
                sharedQueue.takeFirst();
                qDebug() << QString("\nRemoved by thread Consumer %1. Length of queue is: %2").arg(label).arg(sharedQueue.length());
            } else {
                waitCondition.wakeAll();
                qDebug() << QString("\nSignal issued by thread Consumer %1. Length of queue is: %2").arg(label).arg(sharedQueue.length());
            }
        }
    }

private:
    QString label;
};

int main(int argc, char **argv){
    numberOfActiveConsumers = 2;
    numberOfActiveProducers = 2;

    QCoreApplication a(argc, argv);

    Producer producerA("A");
    Producer producerB("B");
    Consumer consumerA("A");
    Consumer consumerB("B");

    producerA.start();
    producerB.start();
    consumerA.start();
    consumerB.start();

    return a.exec();
}
#包括
#包括
#包括
#包括
#包括
#包括
QMutex互斥;
QWaitCondition-waitCondition;
国际生产商协会;
int numberofactiveconsumer;
QList共享队列;
类生产者:公共QThread{
公众:
生产者(QString常量和标签):标签(标签){}
无效运行(){
永远{

qDebug()请与我们分享您获得的调试输出。哦,在
main
中创建每个线程后,您有一个
pthread\u join
。这将不起作用,因为
pthread\u join
直到等待退出的线程才会返回。并且没有任何线程退出。因此,当然,在第一个产品发布后,甚至不会创建其他线程er线程被创建。@kaylum我应该纠正什么?我不应该这样写连接吗?将所有连接调用放在所有创建调用之后。或者将它们全部忽略。只有当你真正关心线程退出后的结果时才需要它们(你不需要,因为它们不退出)或者您希望防止主线程过早退出(我认为您已经通过
a.exec()
)确保了这一点)。@kaylum请写一个包含所有详细信息的正确答案。请与我们共享您得到的调试输出。哦,您有一个
pthread\u join