C++ (Qt)//consumer.hclass Consumer : public QThread{ Q_OBJECTpublic: Consumer(); void run(); static void SetDataSize(const int size); static void SetBufferSize(const int size); static void SetBuffer(char *buf); static void SetBufNotEmpy(QWaitCondition *buf); static void SetBufNotFull(QWaitCondition *buf); static void SetMutex(QMutex *m);signals: void SymbolReceived(char* mes);private: static int DataSize; static int BufferSize; int numUsedBytes; static QMutex *mutex; static QWaitCondition *bufferNotEmpty; static QWaitCondition *bufferNotFull; static char* buffer; //consumer.cppConsumer::Consumer(){ numUsedBytes = 0;}QWaitCondition *Consumer::bufferNotEmpty = NULL;QWaitCondition *Consumer::bufferNotFull = NULL;QMutex *Consumer::mutex = NULL;int Consumer::DataSize = 0;int Consumer::BufferSize = 0;char *Consumer::buffer = NULL; void Consumer::SetDataSize(const int size){DataSize = size; } void Consumer::SetBufferSize(const int size){BufferSize = size; } void Consumer::SetBuffer(char *buf){buffer = buf;} void Consumer::SetBufNotEmpy(QWaitCondition *buf){ bufferNotEmpty = buf;} void Consumer::SetBufNotFull(QWaitCondition *buf){bufferNotFull = buf; } void Consumer::SetMutex(QMutex *m){ mutex = m; } void Consumer::run(){ for (int i = 0; i < DataSize; ++i) { mutex->lock(); if (numUsedBytes == 0) bufferNotEmpty->wait(mutex); mutex->unlock(); qDebug() << buffer[i % BufferSize]; // выводит в дебаге, но хотелось бы тоже самое в гуи выводить, пытаюсь это сделать и ничего не выводит а вообще прога виснет mutex->lock(); --numUsedBytes; bufferNotFull->wakeAll(); mutex->unlock(); } emit SymbolReceived(buffer);}};
C++ (Qt)//producer.hclass Producer : public QThread{ Q_OBJECTpublic: Producer(); void run(); static void SetDataSize(const int size); static void SetBufferSize(const int size); static void SetBuffer(char* buf); static void SetBufNotEmpy(QWaitCondition *buf); static void SetBufNotFull(QWaitCondition *buf); static void SetMutex(QMutex *m);signals: void SymbolProduced(char* mes);private: static int DataSize; static int BufferSize; int numUsedBytes; static QMutex *mutex; static QWaitCondition *bufferNotEmpty; static QWaitCondition *bufferNotFull; static char* buffer;};//producer.cppProducer::Producer(){ numUsedBytes = 0;}QWaitCondition *Producer::bufferNotEmpty = NULL;QWaitCondition *Producer::bufferNotFull = NULL;QMutex *Producer::mutex = NULL;int Producer::DataSize = 0;int Producer::BufferSize = 0;char *Producer::buffer = NULL; void Producer::SetDataSize(const int size){DataSize = size; } void Producer::SetBufferSize(const int size){BufferSize = size; } void Producer::SetBuffer(char *buf){buffer = buf; } void Producer::SetBufNotEmpy(QWaitCondition *buf){ bufferNotEmpty = buf;} void Producer::SetBufNotFull(QWaitCondition *buf){bufferNotFull = buf; } void Producer::SetMutex(QMutex *m){ mutex = m; } void Producer::run(){ qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); for (int i = 0; i < DataSize; ++i) { mutex->lock(); if (numUsedBytes == BufferSize) bufferNotFull->wait(mutex); mutex->unlock(); buffer[i % BufferSize] = "Hello"[(int)qrand() % 5]; //здесь по идее надо выводить созданный символ, но виснет гуи mutex->lock(); ++numUsedBytes; bufferNotEmpty->wakeAll(); mutex->unlock(); } emit SymbolProduced(buffer);}
C++ (Qt)//widget.cppconst int DataSize = 10000;const int BufferSize = 8192; QWaitCondition bufferNotEmpty;QWaitCondition bufferNotFull;QMutex mutex;char *usedBuffer; Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget){ ui->setupUi(this); connect(ui->pushButton, SIGNAL(clicked()),this,SLOT(beginWork())); producer = new Producer; consumer = new Consumer; } Widget::~Widget(){ delete ui;}void Widget::ConsumerSymbol(char* sym){ QString text; for (int i = 0; i < DataSize; ++i) text+=QString(sym[i % BufferSize]); ui->textBrowser->append(text);}void Widget::ProducerSymbol(char* sym){ QString text; for (int i = 0; i < DataSize; ++i) text+=QString(sym[i % BufferSize]); ui->textBrowser_2->append(text);}void Widget::beginWork(){ ui->textBrowser_2->clear(); ui->textBrowser->clear(); usedBuffer = new char[BufferSize]; Producer::SetBufferSize(BufferSize); Producer::SetDataSize(DataSize); Producer::SetMutex(&mutex); Producer::SetBufNotEmpy(&bufferNotEmpty); Producer::SetBufNotFull(&bufferNotFull); Producer::SetBuffer(usedBuffer); Consumer::SetBufferSize(BufferSize); Consumer::SetDataSize(DataSize); Consumer::SetMutex(&mutex); Consumer::SetBufNotEmpy(&bufferNotEmpty); Consumer::SetBufNotFull(&bufferNotFull); Consumer::SetBuffer(usedBuffer); connect(producer,SIGNAL(SymbolProduced(char*)),this, SLOT(ProducerSymbol(char*))); connect(consumer,SIGNAL(SymbolReceived(char*)),this, SLOT(ConsumerSymbol(char*))); producer->start(); consumer->start(); producer->wait(); consumer->wait();}
C++ (Qt)void Producer::run(){ qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); while(true) { // bufferNotFull->wait(mutex); qDebug()<< this->currentThreadId(); if(numUsedBytes == 0) { if(!messages.isEmpty()) { mutex->lock(); buffer[0] = messages.dequeue(); qDebug() << buffer[0]; numUsedBytes++; mutex->unlock(); } }// bufferNotFull->wakeAll(); }}
C++ (Qt)void Consumer::run(){ while(true) { // bufferNotEmpty->wait(mutex); qDebug()<< this->currentThreadId(); if(numUsedBytes != 0) { mutex->lock(); sleep(2); qDebug() << buffer[0]; numUsedBytes--; messages.enqueue(buffer[0]); mutex->unlock(); }// emit SymbolReceived(buffer[0]); // bufferNotEmpty->wakeAll(); } }
C++ (Qt)void Widget::beginWork(){ producer->moveToThread(producer); consumer->moveToThread(consumer); producer->start(); consumer->start();// producer->wait();// consumer->wait();}
C++ (Qt)void Widget::on_pushButton_2_clicked(){ emit newMessage();} // Но почему-то сигнал не приходит до слота потока, и сообщение не добавляется вовсе