多线程应用程序

时间:2012-11-11 09:41:42

标签: multithreading qt qt4

我有一个应用程序,它运行与主GUI线程分开的2个工作线程。

线程1:

  • 需要每100毫秒向线程2发送一些数据。
  • 在每次跑步中睡10分钟。

部首:

class thread1:public QThread
{
    Q_OBJECT
public:
    thread1();
    ~thread1();

signals:
    void wakeThread2();
    void sendValue(int);
    void sleepThread2();

protected:
    void run();

private:
    volatile bool stop;
    int data;
};

实现:

thread1::thread1():stop(false),data(0)
{

}

void thread1::run()
{
    while(!stop)
    {
        ++data;
        if(data==1000)
            data = 0;
        cout<<"IN THREAD 1 with data = "<<data<<endl;
        emit sendValue(data);
        emit wakeThread2();
        emit sleepThread2();
        msleep(10);

    }
}

线程2

部首:

class thread2:public QThread
{
    Q_OBJECT
public:
    thread2();
    ~thread2();

private slots:
    void receiveValue(int);
    void Sleep();

protected:
    void run();

private:
    volatile bool stop;
    int data;
};

实现:

thread2::thread2():stop(false),data(0)
{

}

void thread2::run()
{
    if(!stop)
        cout<<"IN THREAD..............2  with data = "<<data<<endl;
}

void thread2::receiveValue(int x)
{
    data = x;
}

void thread2::Sleep()
{
    msleep(100);
}

主窗口:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    t1 = new thread1;
    t2 = new thread2;

    QObject::connect(t1,SIGNAL(wakeThread2()),t2,SLOT(start()));
    QObject::connect(t1,SIGNAL(sendValue(int)),t2,SLOT(receiveValue(int)));
    QObject::connect(t1,SIGNAL(sleepThread2()),t2,SLOT(Sleep()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_startT1_clicked()
{
    t1->start();
}

输出:

IN THREAD 1 with data = 1
IN THREAD..............2  with data = 1
IN THREAD 1 with data = 2
IN THREAD 1 with data = 3
IN THREAD 1 with data = 4
IN THREAD 1 with data = 5
IN THREAD 1 with data = 6
IN THREAD 1 with data = 7
IN THREAD 1 with data = 8
IN THREAD 1 with data = 9
IN THREAD 1 with data = 10
IN THREAD 1 with data = 11
IN THREAD..............2  with data = 2
IN THREAD 1 with data = 12
IN THREAD 1 with data = 13
IN THREAD 1 with data = 14
IN THREAD 1 with data = 15
IN THREAD 1 with data = 16
IN THREAD 1 with data = 17
IN THREAD 1 with data = 18
IN THREAD 1 with data = 19
IN THREAD 1 with data = 20

线程2中的数据未使用线程1的最新值进行更新,并且GUI窗口完全冻结。如果有更好/更有效的方法用Qt实现多线程应用程序并在线程之间进行通信,请告诉我。

编辑:根据LUCA ,Thread1几乎保持不变......而Thread2.h看起来像这样

Thread2.h

#include <QThread>
#include <QTimer>
#include "iostream"

using namespace std;

class Thread2 : public QThread
{
    Q_OBJECT
public:
    Thread2();
    ~Thread2();
    void startThread();
public slots:
    void receiveData(int);
protected:
    void run();
private:
    volatile bool stop;
    int data;
    QTimer *timer;

};

并且实现是.... Thread2.cpp ..

#include "thread2.h"

Thread2::Thread2():stop(false),data(0)
{
    timer = new QTimer;
    QObject::connect(timer,SIGNAL(timeout()),this,SLOT(start()));
}

Thread2::~Thread2()
{
    delete timer;
}

void Thread2::receiveData(int x)
{
    this->data = x;
}

void Thread2::run()
{
    cout<<"thread 2 .........data  =  "<<data<<endl;
}

void Thread2::startThread()
{
    timer->start(100);
}

并且 mainwindow.cpp 看起来像这样......

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    t1 = new Thread1;
    t2 = new Thread2;

    QObject::connect(t1,SIGNAL(sendData(int)),t2,SLOT(receiveData(int)));
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_start_thread1_clicked()
{
    t1->start();
    t2->startThread();
}

1 个答案:

答案 0 :(得分:1)

在我看来,数据实际上已经更新。但是线程1比线程2快10倍。当你发出睡眠信号时,线程2进入休眠状态100ms,这使得它无法处理其他信号。这些将被放置在队列中,并在控件返回事件循环后立即处理。然后,您将看到更新数据的消息。

无论如何,规范对我来说很奇怪:我读过“线程1需要每隔100毫秒向线程2发送数据......”,但是我看到你每10毫秒做一次,但是你说“线程1本身在其运行的每个循环中睡眠10ms“。什么是线程1应该在剩下的时间做什么?

编辑:我认为这不是你想要的,但我仍然不能完全确定我理解你在寻找什么。不是一个完整或良好的实现,只是为了提出这个想法:

#include <QCoreApplication>
#include <QTimer>
#include <QThread>

class Thread1 : public QThread
{
   Q_OBJECT
public:
   explicit Thread1() :
      data(0) {
      // Do nothing.
   }

   void run() {
      while (true) {
         data++;
         qDebug("Done some calculation here. Data is now %d.", data);
         emit dataChanged(data);
         usleep(10000);
      }
   }

signals:
   void dataChanged(int data);

private:
   int data;
};

class Thread2 : public QObject
{
   Q_OBJECT
public:
   explicit Thread2() {
      timer = new QTimer;
      connect(timer, SIGNAL(timeout()), this, SLOT(processData()));
      timer->start(100);
   }

   ~Thread2() {
      delete timer;
   }

public slots:
   void dataChanged(int data) {
      this->data = data;
   }

   void processData() {
      qDebug("Processing data = %d.", data);
   }

private:
   QTimer* timer;
   int data;
};

int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);

   Thread1 t1;
   Thread2 t2;
   qApp->connect(&t1, SIGNAL(dataChanged(int)), &t2, SLOT(dataChanged(int)));
   t1.start();

   return a.exec();
}

#include "main.moc"

输出结果为:

Done some calculation here. Data is now 1.
Done some calculation here. Data is now 2.
Done some calculation here. Data is now 3.
Done some calculation here. Data is now 4.
Done some calculation here. Data is now 5.
Done some calculation here. Data is now 6.
Done some calculation here. Data is now 7.
Done some calculation here. Data is now 8.
Done some calculation here. Data is now 9.
Done some calculation here. Data is now 10.
Processing data = 10.
Done some calculation here. Data is now 11.
Done some calculation here. Data is now 12.
Done some calculation here. Data is now 13.
Done some calculation here. Data is now 14.
Done some calculation here. Data is now 15.
Done some calculation here. Data is now 16.
Done some calculation here. Data is now 17.
Done some calculation here. Data is now 18.
Done some calculation here. Data is now 19.
Processing data = 19.
Done some calculation here. Data is now 20.
Done some calculation here. Data is now 21.
Done some calculation here. Data is now 22.
Done some calculation here. Data is now 23.
Done some calculation here. Data is now 24.
Done some calculation here. Data is now 25.
Done some calculation here. Data is now 26.
Done some calculation here. Data is now 27.
Done some calculation here. Data is now 28.
Processing data = 28.
...

请注意,Thread2实际上是应用程序的主线程(即UI线程)。如果需要,将对象移动到另一个线程。