【发布时间】:2015-12-20 09:04:38
【问题描述】:
共享队列是一个。生产者和消费者都是两个。
下面是输出,之后我已经粘贴了程序:
我的问题是打印语句qDebug () << "\nConsumer: " << tId;,在顶部仍然没有先打印。我想知道为什么。
Producer 140588830992128 couldn't push any data since queue was already full. Length of queue is: 10
Removed by thread Consumer: 140588814206720 , Length of queue is: 9
Removed by thread Consumer: 140588814206720 , Length of queue is: 8
Removed by thread Consumer: 140588814206720 , Length of queue is: 7
Removed by thread Consumer: 140588814206720 , Length of queue is: 6
Removed by thread Consumer: 140588814206720 , Length of queue is: 5
Consumer: 140588814206720
Removed by thread Consumer: 140588814206720 , Length of queue is: 4
Removed by thread Consumer: 140588814206720 , Length of queue is: 3
Removed by thread Consumer: 140588814206720 , Length of queue is: 2
Consumer: 140588814206720
Removed by thread Consumer: 140588814206720 , Length of queue is: 1
Consumer: 140588814206720
Removed by thread Consumer: 140588814206720 , Length of queue is: 0
这是我编写的程序:
#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 `Producer` threads.
void *producerThreadFunction (void *arg) {
Q_UNUSED (arg);
while (1) {
pthread_t tId = pthread_self();
qDebug () << "\nProducer: " << tId;
pthread_mutex_lock (&mutexVariable);
if (sharedQueue.length () < 10) {
sharedQueue.push_back (1);
qDebug () << "\nPushed by Producer " << tId << ": " << "Length of queue is: " << sharedQueue.length ();
}
else {
qDebug () << "\nProducer " << tId << " has no work to do since quque is full, 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 `Consumer` threads.
void *consumerThreadFunction (void *arg) {
Q_UNUSED (arg);
while (1) {
pthread_t tId = pthread_self ();
qDebug () << "\nConsumer: " << tId;
pthread_mutex_lock (&mutexVariable);
if (sharedQueue.length () > 0) {
for (int u = 0; u < sharedQueue.length (); u++) {
sharedQueue.pop_front ();
qDebug () << "\nRemoved by thread Consumer: " << tId << ", Length of queue is: " << sharedQueue.length ();
}
}
else {
pthread_cond_signal (&conditionVariable);
qDebug () << "\nSignal issued by thread Consumer: " << tId << ", Length of queue is: " << sharedQueue.length ();
}
pthread_mutex_unlock (&mutexVariable);
}
return NULL;
}
int main (int argc, char *argv[]) {
numberOfActiveProducers = 2;
numberOfActiveConsumers = 2;
sizeOfSharedQueue = 10;
// Producer threads creation
pthread_t producerA;
pthread_t producerB;
if (pthread_create (&producerA, NULL, producerThreadFunction, NULL)) {
fprintf (stderr, "Error creating thread Producer A\n");
return 1;
}
if (pthread_create (&producerB, NULL, producerThreadFunction, NULL)) {
fprintf (stderr, "Error creating thread Producer B\n");
return 1;
}
// Consumer threads creation
pthread_t consumerA;
pthread_t consumerB;
if (pthread_create (&consumerA, NULL, consumerThreadFunction, NULL)) {
fprintf (stderr, "Error creating thread Consumer A\n");
return 1;
}
if (pthread_create (&consumerB, NULL, consumerThreadFunction, NULL)) {
fprintf (stderr, "Error creating thread Consumer B\n");
return 1;
}
// Joining every thread
if (pthread_join (producerA, NULL)) {
fprintf (stderr, "Error joining thread Producer A\n");
return 2;
}
if (pthread_join (producerB, NULL)) {
fprintf (stderr, "Error joining thread Producer B\n");
return 2;
}
if (pthread_join (consumerB, NULL)) {
fprintf (stderr, "Error joining thread Consumer B\n");
return 2;
}
if (pthread_join (consumerA, NULL)) {
fprintf (stderr, "Error joining thread Consumer A\n");
return 2;
}
QApplication a (argc, argv);
MainWindow w;
w.show ();
return a.exec ();
}
添加了带有std::cerr 的屏幕截图。输出没有区别:
【问题讨论】:
-
你为什么要标记这个C?您似乎正在编写 Qt C++。
-
我不知道
qDebug()做了什么。它是线程安全的吗?如果将其替换为cout<< ... << endl;会发生什么? -
您提供的输出与您在此处引用的程序不匹配。此外,许多 pthread 调用没有检查任何错误。也就是说,为什么不使用 C++ 线程?
-
根据他们的documentation,如果没有明确声明是线程安全的,那么函数不是。而qDebug() 对此一无所知。所以它是线程不安全的。所以可能发生的情况是一个调用覆盖了前一个调用的值,因为它可能在打印之前使用静态缓冲区。我认为,因此,您的行为未定义。
-
@I3x 我不能使用 std::cout。我今天试过了,但没有打印出来。使用 qDebug() 的功能是它自己打印该值。特别是在编写 QML 时,qDebug 是非常必要的,因为 cout 只在程序结束时打印。顺便说一句,这一次,当我停止程序时,它根本没有打印任何东西。这正是我尝试过的:
while (1) { pthread_t tId = pthread_self (); //qDebug () << "\nConsumer: " << tId; std::cout <<"\nConsumerjjj: ";
标签: c++ multithreading pthreads producer-consumer